Closures and Functional Programming

20.1 Anonymous Functions

double := fn (x int) int { return x * 2 }
println(double(4))
nums := [1, 2, 3]
println(nums.map(fn (x int) int { return x * x }))

20.2 Closures (Explicit Capture)

Variables are captured by copy in the [...] list. mut captures allow modification of the closure's own copy. Capturing references (&x) shares state.

fn make_counter() fn () int {
	mut count := 0
	return fn [mut count] () int {       // explicit capture list
		count++
		return count
	}
}

fn main() {
	c := make_counter()
	println(c())   // 1
	println(c())   // 2
	factor := 3
	mul := fn [factor] (x int) int { return x * factor }   // capture by value (copy)
	println(mul(5))
}

20.3 Higher-Order Functions

fn compose(f fn (int) int, g fn (int) int) fn (int) int {
	return fn [f, g] (x int) int { return f(g(x)) }
}
inc := fn (x int) int { return x + 1 }
sq := fn (x int) int { return x * x }
println(compose(sq, inc)(3))   // 16

20.4 Functional Array Pipelines

import arrays
words := ['apple', 'Banana', 'cherry', 'date']
result := words
	.filter(it.len > 4)
	.map(it.to_lower())
	.sorted()
println(result)
println(arrays.fold(words, 0, fn (acc int, w string) int { return acc + w.len }))
grouped := arrays.group_by[int, string](words, fn (w string) int { return w.len })
println(grouped)