4
function makeIncreaseByFunction(increaseByAmount) {
  return function (numberToIncrease) {
    return numberToIncrease + increaseByAmount;
  };
}

makeIncreaseByFunction(3)(10);

Updated for Clarity Can somebody explain why the (3)(10) is written the way it is? I understand that 10 is being supplied as an argument to the inner function, but why is syntactically notated like this? If we had three nested functions, would the arguments always be written in order as in (3)(10)(20)?

jjj
  • 123
  • 1
  • 6
  • 2
    By calling the first function, you are being returned a function. – Cole Tobin Jul 31 '13 at 23:19
  • 1
    That looks like a closure to me. See http://stackoverflow.com/a/111200 – Robert Harvey Jul 31 '13 at 23:19
  • Right, I get that part. Referencing the link you just posted... my equivalent question there would be... explain more about what is going on syntactically at the "var bar = foo(2); // bar is now a closure. bar(10);" part. How is 10 getting passed into the inner function syntactically? – jjj Jul 31 '13 at 23:22
  • What do you mean by _syntactically_? I don't think anything gets passed syntactically—once the syntax is parsed the engine does all the work completely ignorant of the syntax. – DaoWen Jul 31 '13 at 23:29
  • hmm. I guess for some reason the way that this syntax is being parsed seems arbitrary or abstract to me (I am fairly new to Javascript from Ruby) – jjj Jul 31 '13 at 23:39
  • 1
    `()` is operator to call whatever is on the left as function. Try `null()`. Get it? `+` is operator to sum whatever is on the left and right, but then, what is `5 + 5 + 5`. Well, `( 5 + 5 ) + 5`. In the same way `whatever()()` is `( whatever() ) ()` e.g. call `whatever` as function, and then call the result of that as a function... – Esailija Aug 01 '13 at 00:02
  • A Ruby analogue would be `make_increase_by = ->(amount){ ->(to_increase){ to_increase + amount } }` (I'm not sure how familiar you are with anonymous functions in Ruby). You are then calling the outer lambda to return the inner lambda and then calling it again with `make_increase_by.(3).(10)`. There is no difference between this implementation and the above javascript apart from syntax style. – Aaron Cronin Aug 01 '13 at 09:05

3 Answers3

5

With intermediate variable:

var increaseBy3 = makeIncreaseByFunction(3);
var foo = increaseBy3(10);

Without intermediate variable:

var foo = makeIncreaseByFunction(3)(10);

In both cases, the first invokation passes the argument 3 to makeIncreaseByFunction, and as a result it returns the inner function that has closed over increaseByAmount with the value of 3. Whether you create a variable for the intermediate function returned by makeIncreaseByFunction, or just invoke it directly, it does the same thing.


Can you explain a little bit more detail about how in var foo = makeIncreaseByFunction(3)(10); the 10 is getting to the inner function? It just looks syntactically different from how arguments usually get passed in Javascript to me. – ggg

makeIncreaseByFunction(3) returns a function, specifically the "inner function" defined inside makeIncreaseByFunction. As will all functions, you call it with the function ( arguments ) syntax. You can write it like this if it makes more sense to you this way:

( makeIncreaseByFunction(3) )(10)

What happens here is makeIncreaseByFunction(3) gets called first and returns the ⟪inner function⟫, and then we call ⟪inner function⟫(10).

If you were evaluating this by hand (I think this is what you meant by "syntactically"), you could think of it happening step-by-step like this:

// Original invocation
var foo = makeIncreaseByFunction(3)(10);

// Substitute the definition of makeIncreaseByFunction
var foo = (function (increaseByAmount) {
  return function (numberToIncrease) {
    return numberToIncrease + increaseByAmount;
  };
})(3)(10);


// Apply the parameter 3
var foo = (function (numberToIncrease) {
  return numberToIncrease + 3;
})(10);


// Apply the parameter 10
var foo = 10 + 3;

// Final result
var foo = 13;

Note: If you want to be technical, all we're doing here is two Beta reductions—but unless you have background with the Lambda Calculus that will probably confuse you more than it will help you!

DaoWen
  • 32,589
  • 6
  • 74
  • 101
  • Thanks. Can you explain a little bit more detail about how in `var foo = makeIncreaseByFunction(3)(10);` the 10 is getting to the inner function? It just looks syntactically different from how arguments usually get passed in Javascript to me. – jjj Jul 31 '13 at 23:25
0

makeIncreaseByFunction(3) would return function so the syntax for then calling it with 10 would be makeIncreaseByFunction(3)(10).

This is easy to understand as if you have a function foo (imagine that the return of makeIncreaseByFunction(3) is such a function, they are evaluated identically), you would then call it with 10 using foo(10).

As for how the value of 10 is being 'passed', this is the wrong way to thing about things.

You must realise that in Javascript functions are first class objects. Instead of passing the value to the inner function, you are creating a function that does what you want and then calling it with the outer argument.

It is the same as using a variable to add within a function in a non-functional language except functions can be dynamically created at runtime and the values of any variable in their definition can be set influencing their internal consistency.

The closure refers to the fact that the created function is a black-box which hides the variable used to initialize it, despite still using that variable to increment the value it is called with.

Aaron Cronin
  • 2,093
  • 14
  • 13
  • Ok, after reading this a second time I get it. Key word for me out of your first sentence being "return." That's the "pivot point" if you will on which the whole thing turns... that's where the inner function basically takes the syntactic place of the outer function, so I see how 10 is then being supplied as the argument. Maybe that is an awful way for me to describe it, but suffice it to say I get syntactically how it is fitting together now. – jjj Jul 31 '13 at 23:48
  • The important thing to understand is that in a language with first-class functions, returning a function or storing a function in a variable is no different from processing an Integer or a String - apart from the fact that you can call the function later. – Aaron Cronin Aug 01 '13 at 09:02
0

var increaseBy3 = makeIncreaseByFunction(3); is the exact same as (disregarding the local storage for the variable increaseByAmount):

var increaseBy3 = function (numberToIncrease) {
    return numberToIncrease + 3;
};

So of course now you can call increaseBy3(10) and get 13. increaseBy3 just references as anonymous function which returns its first argument plus 3.

Paul
  • 139,544
  • 27
  • 275
  • 264