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.