A function declared inside another function can read and update names from the enclosing scope. The captured binding lives as long as the inner function does, so a factory can hand out a function that owns private mutable state.

Program

Play the program to build a counter closure and call it twice.

closures.dart
Replay: real traced execution (multi-file project)
int Function() makeCounter() {
  var count = 0;
  return () {
    count += 1;
    return count;
  };
}

void main() {
  var next = makeCounter();
  var a = next();
  var b = next();
  print('$a $b');
}
  1. call ← makeCounter()

    9void main() {10  var next = makeCounter();11  var a = next();
    values this stepmakeCounter()call
  2. count ← 0

    1int Function() makeCounter() {2  var count = 0;3  return () {
    values this step0count
  3. return value ← <closure capturing count>

    2var count = 0;3return () {4  count += 1;
    values this step<closure capturing count>return value
  4. next ← <closure>

    9void main() {10  var next = makeCounter();11  var a = next();
    values this step<closure>next
  5. call ← next()

    10var next = makeCounter();11var a = next();12var b = next();
    values this stepnext()call
  6. count ← 1

    3return () {4  count += 1;5  return count;
    values this step0 1count
  7. return value ← 1

    4  count += 1;5  return count;6};
    values this step1return value
  8. a ← 1

    10var next = makeCounter();11var a = next();12var b = next();
    values this step1a
  9. call ← next()

    11var a = next();12var b = next();13print('$a $b');
    values this stepnext()call
  10. count ← 2

    3return () {4  count += 1;5  return count;
    values this step1 2count
  11. return value ← 2

    4  count += 1;5  return count;6};
    values this step2return value
  12. b ← 2

    11var a = next();12var b = next();13print('$a $b');
    values this step2b
  13. print('$a $b');

    12  var b = next();13  print('$a $b');14}
    output1 2
    values this step1a2b
closure An inner function captures names from its enclosing scope.
captured mutation `count += 1` updates the same binding across calls; the closure carries the state.
factory function `int Function() makeCounter()` returns a fresh zero-argument function with its own private `count`.