A closure is an unnamed function value. Its type is Fn, and it is a full expression: it may be assigned to a local, passed to another function, stored in a list, returned, or called directly.
let add: Fn = |a, b| a + b;
add(2, 3)
The pipes declare parameters and the following expression is the result. Parameters may have type annotations:
let double: Fn = |value: number| value * 2;
let greet: Fn = || "Hello!";
Closures are execution-local values. They cannot be stored in Memory variables, App variables, or other persisted declarations.
Capture surrounding values
A closure can read locals from the surrounding program:
let factor = 3;
let multiply: Fn = |value: number| value * factor;
multiply(4)
Here multiply captures factor and returns 12.
Use a block body
Use braces for several statements. The final expression becomes the result:
let percentage: Fn = |value: number, maximum: number| {
let ratio = value / maximum;
ratio * 100
};
percentage(30, 40)
Closures calculate values. Their bodies cannot assign persistent state or produce output effects.
Pass a closure to another function
A function can accept Fn like any other typed value:
fn apply(operation: Fn, value: number) {
operation(value)
}
let double: Fn = |value: number| value * 2;
apply(double, 5)
The receiving function decides when to call the closure and which arguments to supply. In this example, apply() returns 10.
An immediately written closure can also be called:
(|value| value + 1)(4)
Use a named fn definition when behavior should be part of a module’s reusable public code. Use an Fn closure when behavior belongs to one execution or needs to capture its surroundings.
The next lesson, Working with lists, brings every practical list operation together. It shows how lists receive closures and how an execution-local List<Fn> works.