Nyx by Example

Closures

Closures are functions that capture variables from their enclosing scope. In Nyx, functions are first-class values of type Fn — they can be returned from functions, stored in variables, and passed as arguments.

Code

// Closures: función que retorna closure, tipo Fn, captura de entorno

fn make_counter(start: int) -> Fn {
    var count: int = start
    fn increment() -> int {
        count = count + 1
        return count
    }
    return increment
}

fn make_adder(n: int) -> Fn {
    fn add(x: int) -> int {
        return n + x
    }
    return add
}

fn apply(f: Fn, value: int) -> int {
    return f(value)
}

fn main() -> int {
    // Counter: cada llamada retorna el siguiente valor
    let counter: Fn = make_counter(0)
    print("counter: " + int_to_string(counter()))
    print("counter: " + int_to_string(counter()))
    print("counter: " + int_to_string(counter()))

    // Dos contadores independientes
    let c2: Fn = make_counter(10)
    print("c2: " + int_to_string(c2()))
    print("c2: " + int_to_string(c2()))

    // Adder: closure que captura n del entorno
    let add5: Fn = make_adder(5)
    print("add5(3) = " + int_to_string(add5(3)))
    print("add5(10) = " + int_to_string(add5(10)))

    // Pasar closure como argumento
    let add100: Fn = make_adder(100)
    print("apply(add100, 7) = " + int_to_string(apply(add100, 7)))

    return 0
}

Output

counter: 1
counter: 2
counter: 3
c2: 11
c2: 12
add5(3) = 8
add5(10) = 15
apply(add100, 7) = 107

Explanation

A closure is a nested function that references variables from its enclosing function. In make_counter, the inner function increment captures the count variable declared in the outer scope. Each time increment is called, it reads and modifies its own copy of count — this is called a shared environment.

The return type -> Fn indicates that a function returns another function. The Fn type is the generic function type in Nyx; it represents any callable value, regardless of its specific parameter and return types.

Each call to make_counter creates an independent closure with its own private count. The two counters counter and c2 do not interfere with each other — they start at different values and advance independently.

The apply function demonstrates higher-order functions: it receives a Fn and an int, and calls the function with the value. This pattern is the foundation of functional programming styles — mapping, filtering, and composing behavior by passing functions as data.

← Previous All recipes →

Source: examples/by-example/10-closures.nx