# Closures, Function Types and Tear-offs — Dart

Source: https://www.skillbyai.com/en/dart/fn-closures

> Use anonymous functions, closures, typedefs and tear-offs.

## Functions as values

**Anonymous functions** (lambdas) are written `(params) { body }` or `(params) => expression` and are passed everywhere: `list.map((p) => p.title)`, event handlers, sorting comparators. A **closure** captures variables from its surrounding scope and can read and modify them later, which powers counters, callbacks and memoisation. **Function types** are written like `int Function(int a, int b)`, and **`typedef`** gives them names: `typedef PriceRule = double Function(double price);`, making APIs that accept callbacks readable. A **tear-off** turns an existing function or method into a function value without writing a lambda: `names.forEach(print)` or `items.map(Product.fromJson)`, and constructor tear-offs (`List.generate(3, Item.new)`) work too. Tear-offs are preferred over wrapper lambdas such as `(x) => print(x)`, which the linter flags. Closures in loops capture a fresh variable per iteration in `for` loops, avoiding a classic JavaScript bug.

## Closures, typedefs and tear-offs

Building pricing rules as functions and composing them.

```dart
typedef PriceRule = double Function(double price);

PriceRule percentOff(double percent) => (price) => price * (1 - percent / 100);   // returns a closure
PriceRule flatOff(double amount) => (price) => price - amount < 0 ? 0 : price - amount;

double applyAll(double price, List<PriceRule> rules) =>
    rules.fold(price, (current, rule) => rule(current));

int Function() makeCounter() {
  var count = 0;
  return () => ++count;            // captures and modifies count
}

void main() {
  final festive = [percentOff(10), flatOff(50)];
  print(applyAll(1000, festive));   // 850.0

  final next = makeCounter();
  next();
  print(next());                    // 2

  final titles = ['pen', 'ink'];
  titles.map((t) => t.toUpperCase()).forEach(print);   // tear-off of print
}
```

## Recipes as index cards

Function values are recipe cards you can hand around: "apply 10% off", "subtract Rs 50". A checkout can take a stack of cards and apply them in order without knowing what each one does inside.

**Quiz:** What is a tear-off in Dart?

- [ ] A way to delete a function
- [ ] A type of exception
- [ ] A collection literal
- [x] Using a function or method name as a function value without wrapping it in a lambda

*Answer:* Using a function or method name as a function value without wrapping it in a lambda. Tear-offs like list.forEach(print) pass existing functions directly.
