Learning path

Full curriculum

Full curriculum

Unit content

Lexical closures and captured environments

A closure is a function value together with the environment needed to interpret its free variables later.

Consider:

function make_adder(k):
    function add(x):
        return x + k
    return add

After make_adder(10) returns, its local call frame can disappear, yet the returned function must still know that k means 10. The closure preserves that binding.

Formally, a closure can be modeled as a pair

$$\langle \lambda x.e,\rho\rangle,$$

where $\lambda x.e$ is the function code and $\rho$ is the lexical environment at the point where the function was created. Applying the closure extends the saved environment with a binding for the argument and evaluates the body there.

A closure captures bindings, not merely the textual values visible when the function is written. If a captured binding refers to mutable storage, later updates may be visible through the closure because the environment can preserve a location rather than copy a value.

Closures are the runtime mechanism that makes lexical scope and first-class nested functions coexist. They explain callback state, function factories and many iterator or asynchronous-programming patterns without relying on global state.