Skip to content

Closures & Lambdas

Inline Lambdas

wyn
var nums = [1, 2, 3, 4, 5]
var doubled = nums.map(fn(x: int) -> int { return x * 2 })
var big = nums.filter(fn(x: int) -> bool { return x > 3 })

Void Lambdas

Lambdas without a return type — for side effects:

wyn
var items = [1, 2, 3]
items.each(fn(x: int) { println(x.to_string()) })

5.times(fn() { println("tick") })

Multiline Lambdas

Lambda bodies can contain multiple statements:

wyn
var processed = nums.map(fn(x: int) -> int {
    var squared = x * x
    var adjusted = squared + 1
    return adjusted
})

nums.each(fn(x: int) {
    var label = "item: " + x.to_string()
    println(label)
})

Chained Operations

wyn
var result = [1, 2, 3, 4, 5]
    .filter(fn(x: int) -> bool { return x > 2 })
    .map(fn(x: int) -> int { return x * 10 })
println(result.join(", "))  // 30, 40, 50

Closures with Captures

Closures capture variables from the enclosing scope:

wyn
var x = 10
var add_x = fn(n: int) -> int { return n + x }
println(add_x(5).to_string())  // 15

Returning Closures

Functions can return closures:

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

var add5 = make_adder(5)
var add10 = make_adder(10)
println(add5(3).to_string())   // 8
println(add10(3).to_string())  // 13

Closures as Arguments

wyn
fn apply(arr: [int], f: fn(int) -> int) -> [int] {
    return arr.map(f)
}

var result = apply([1, 2, 3], fn(x: int) -> int { return x * x })
// result = [1, 4, 9]

Sort with Comparator

wyn
var nums = [5, 3, 1, 4, 2]
var sorted = nums.sort(fn(a: int, b: int) -> int { return a - b })

Mutable Captures

Closures capture variables by reference — mutations are visible to the caller:

wyn
var count = 0
var items = [1, 2, 3, 4, 5]
items.each(fn(x: int) { count = count + x })
println(count.to_string())  // 15
wyn
var n = 0
5.times(fn() { n = n + 1 })
println(n.to_string())  // 5
wyn
var count = 0
var inc = fn() -> int {
    count = count + 1
    return count
}
println(inc().to_string())  // 1
println(inc().to_string())  // 2
println(inc().to_string())  // 3

This works with multi-statement block bodies. The captured variable is modified in-place — subsequent calls see the updated value.

wyn
var total = 0
var items = [10, 20, 30]
var add_to_total = fn(n: int) {
    total = total + n
}
for item in items {
    add_to_total(item)
}
println(total.to_string())  // 60

Arrow Syntax

For single-expression lambdas, use =>:

wyn
var double = fn(x: int) => x * 2
var nums = [1, 2, 3].map(fn(x: int) => x * 10)

See Also

MIT License