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.
// 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 }
counter: 1 counter: 2 counter: 3 c2: 11 c2: 12 add5(3) = 8 add5(10) = 15 apply(add100, 7) = 107
How it works
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.