flutter
/

Dart Lambda Functions – Anonymous Functions and Closures

Last Sync: Today

On this page

10
0%
5 min read
Remaining
5 minleft

Click any section to jump — progress syncs automatically

flutter

Dart Lambda Functions – Anonymous Functions and Closures

What are Lambda Functions?

Lambda functions, also known as anonymous functions or function literals, are functions that are not bound to an identifier (they don't have a name). They are often used as short, disposable functions that are passed as arguments to higher‑order functions or assigned to variables. Lambdas are a key feature of functional programming and are widely used in Dart, especially when working with collections.

Syntax of Lambda Functions

Dart supports two syntaxes for lambda functions: block body and arrow syntax (fat arrow). Both can capture variables from their surrounding scope.

Block Body Syntax

DARTRead-only
1
(parameters) {
  // function body
  return value;
}

For example:

DARTRead-only
1
void main() {
  var add = (int a, int b) {
    return a + b;
  };
  print(add(3, 5)); // 8
}

Arrow Syntax (Fat Arrow)

For single‑expression functions, you can use the arrow syntax =>. The result of the expression is implicitly returned.

DARTRead-only
1
(parameters) => expression
DARTRead-only
1
void main() {
  var multiply = (int a, int b) => a * b;
  print(multiply(4, 3)); // 12
}

Assigning Lambdas to Variables

Lambdas are first‑class objects, so you can assign them to variables and use them like any other value.

DARTRead-only
1
void main() {
  // Assign a lambda to a variable
  var greet = (String name) => 'Hello, $name!';

  print(greet('Alice')); // Hello, Alice!

  // The type is inferred as `String Function(String)`
}

Passing Lambdas as Arguments

This is the most common use case. Many Dart methods accept functions as parameters, such as forEach, map, where, reduce, and fold. You can pass a lambda directly.

DARTRead-only
1
void main() {
  var numbers = [1, 2, 3, 4, 5];

  // Using lambda with forEach
  numbers.forEach((num) {
    print('Square of $num is ${num * num}');
  });

  // Using lambda with map (arrow syntax)
  var doubled = numbers.map((n) => n * 2).toList();
  print(doubled); // [2, 4, 6, 8, 10]

  // Using lambda with where
  var even = numbers.where((n) => n % 2 == 0).toList();
  print(even); // [2, 4]
}

Closures – Capturing Variables

A closure is a lambda that captures variables from the scope where it was defined. It 'closes over' those variables, keeping them alive even after that scope exits. This is a powerful feature for creating stateful functions.

DARTRead-only
1
Function makeCounter() {
  int count = 0; // captured variable
  return () => ++count;
}

void main() {
  var counter = makeCounter();
  print(counter()); // 1
  print(counter()); // 2
  print(counter()); // 3

  var anotherCounter = makeCounter();
  print(anotherCounter()); // 1 (separate closure, separate state)
}

In this example, each invocation of makeCounter creates a new closure with its own count variable. The lambda captures count and increments it each time.

Using Lambdas with Callbacks

Lambdas are ideal for short‑lived callbacks, such as event handlers in UI programming (e.g., Flutter).

DARTRead-only
1
// Example: simulating a button click
void onButtonClick(void Function() callback) {
  print('Button clicked');
  callback();
}

void main() {
  // Passing a lambda as a callback
  onButtonClick(() {
    print('Do something after click');
  });
}

Lambda vs Named Function

    • Named functions are reusable, can be called from anywhere, and are easier to debug (they appear in stack traces).
    • Lambdas are more concise and can capture local variables easily; they are perfect for one‑off operations.

Key Takeaways

    • Lambdas (anonymous functions) are functions without a name.
    • Syntax: block body (p) { ... } or arrow (p) => expr.
    • They can be assigned to variables, passed as arguments, and returned from other functions.
    • Closures capture variables from the surrounding scope, enabling stateful behavior.
    • Widely used with collection methods (forEach, map, where, etc.) and in event‑driven programming.

Try it yourself

void main() {
  var numbers = [1, 2, 3, 4, 5];
  
  // Use a lambda with map
  var squares = numbers.map((n) => n * n).toList();
  print('Squares: $squares');
  
  // Use a lambda with where
  var evens = numbers.where((n) => n % 2 == 0).toList();
  print('Evens: $evens');
}

Test Your Knowledge

Q1
of 4

What is another name for a lambda function?

A
Closure
B
Anonymous function
C
Arrow function
D
All of the above
Q2
of 4

What is the output of this code? void main() { var fun = (int x) => x * 2; print(fun(5)); }

A
5
B
10
C
25
D
Error
Q3
of 4

What does a closure capture?

A
Parameters of the function
B
Variables from the surrounding scope
C
Global variables only
D
Nothing
Q4
of 4

Which syntax is used for a single‑expression lambda?

A
=>
B
->
C
=>
D
{}

Frequently Asked Questions

What is the difference between a lambda and a function?

A lambda is just a function without a name. In Dart, functions are objects, and lambdas are a concise way to create function objects on the fly. They behave identically to named functions.

Can a lambda have multiple statements?

Yes, if you use the block body syntax { ... }. Inside the braces you can have multiple statements, and you must use an explicit return if the lambda should return a value. The arrow syntax is limited to a single expression.

What is a closure exactly?

A closure is a lambda that references variables from its lexical scope. It 'closes over' those variables, allowing them to persist as long as the closure itself exists, even after the original scope is gone. This enables functions with private state.

Can I use type annotations with lambdas?

Yes, you can annotate parameter types and the return type, though it's often inferred. For example: (int a, int b) => a + b.

How do I return a value from a lambda with block body?

Use the return keyword explicitly, just like in a regular function.

Are lambdas less performant than named functions?

No, there is no performance difference. Dart compiles both to similar code. However, creating many closures in a loop might have some overhead, but it's usually negligible.

Previous

dart abstract classes

Next

dart higher order functions

Related Content

Need help?

Explore our comprehensive docs or start a chat with our tech experts.