Dart. Where argument of anonymous function came from?

351 Views Asked by At

In example below there (num i) stuff, where it get it's value when makeAddr() called ?

Function makeAdder(num addBy) {
  return (num i) => addBy + i;
}

void main() {
  // Create a function that adds 2.
  var add2 = makeAdder(2);

  // Create a function that adds 4.
  var add4 = makeAdder(4);

  assert(add2(3) == 5);
  assert(add4(3) == 7);
}
2

There are 2 best solutions below

0
lrn On BEST ANSWER

The makeAdder function returns function. The function it returns is created by evaluating the function expression (num i) => addBy + i. When you evaluate a function expression you create a function value. The function value is also called a closure because it contains ("closes over") all the "free" variables in the function body - those that are not declared by the function expression itself

In this case the function expression (num i) => addBy + i contains the free variable addBy. The function value/closure knows what that variable means - it's the parameter of the call to makeAdder that the function expression is evaluated in. Every call to makeAdder creates a new addBy variable, and every call also creates a new closure closing over that new variable.

The closure is not just storing the value of the variable, it's referencing the variable itself. You can see that if your closure changes the value of variable.

Example:

/// Creates a counter function which returns a new value each call.
///
/// The counter function starts at [start] and increments by [step]
/// each time it is called.
int Function() makeCounter([int start = 1, int step = 1]) {
  var value = start - step;
  return () => value += step;
}

main() {
  var countFrom1 = makeCounter();
  var countFast = makeCounter(1, 2);
  var countFrom100 = makeCounter(100);

  // Prints 1, 2, 3, 4, 5:
  for (var i = 0; i < 5; i++) print(countFrom1()); 

  // Prints 1, 3, 5, 7, 9:
  for (var i = 0; i < 5; i++) print(countFast()); 

  // Prints 100, 101, 102, 103, 104:
  for (var i = 0; i < 5; i++) print(countFrom100()); 

  print(countFrom1());  // Prints 6.
}
0
Randal Schwartz On

It's a closure. When makeAdder returns, it's returning a function that already has addBy in scope, and that scope is frozen.