Note: None of this is implemented.

A closure may be viewed as a function that preserves its state from one invocation to the next. Because closures preserve their state, they are useful for:

Closure Definition

A closure definition resembles a function definition. There are three key differences: the name is omitted, the return value type(s) are be omitted (and inferred), and the initial value of the preserved state is specified,

For example:

mut counter = fn(n i32) [cnt = 0]: cnt += n

// Closure use
counter(1)        // 1
counter(2)        // 3

In this case, the closure takes no parameters. It infers that the return value is an integer.

This closure's state is explicitly defined within square brackets after the parameter list. The closure's state is a semi-colon-separated collection of named closure variables. Each closure variable specifies its initial value (and implicitly its type). If no initial value is specified, it will use the current value of that same-named variable in the outer scope.

Each time the closure is called, it increments the value held by cnt. which is why it returns a different value each time it is called.

A closure's state is bound by value, which means it is created using a copy of the bound variable(s). Any change to cnt within the closure has no impact on the outer scope's cnt variable. (Binding state by reference is also possible, but must be always done explicitly such that the value is a reference.)

Explicit specification of the closure's state has several benefits:

Notice how the closure's logic accesses its state using bound closure variables.

Closures are values

Although closures may be viewed as functions with a persistent state, it is more useful and accurate to view them as a data value that carries an associated function (method). Later pages add important details on additional capabilities of closures: