Basic Closures

  -- [capture_list](params): ReturnType { body }
var add = [](x: i32, y: i32): i32 { return x + y; };
debug.print("{}\n", .{add(3, 4)});   -- 7

-- capturing from outer scope
var offset: i32 = 10;
var addOffset = [offset](x: i32): i32 { return x + offset; };
debug.print("{}\n", .{addOffset(5)});   -- 15
  

Moving Into Closures

Non-Copy values must be moved:

  var name = try String::from(alloc, "World");
var greet = [move name](): void {
    debug.print("Hello, {}!\n", .{name});
};
-- name is gone from this scope
greet();
  

Closures as Parameters

  fn applyTwice[T](f: fn(*mut T): void, val: *mut T) {
    f(val);
    f(val);
}

var x: i32 = 0;
applyTwice([&x](_: *mut i32) { x += 1; }, &x);
debug.print("{}\n", .{x});   -- 2
  

Closures With Collections

  fn filter[T](items: []T, pred: fn(*const T): bool, alloc: Allocator): ![]T {
    var result = List[T]::new();
    errdefer result.deinit(alloc);

    for item in items {
        if pred(item) {
            try result.push(alloc, item.*);
        }
    }
    return result.intoSlice();
}

var numbers = [_]i32{ 1, 2, 3, 4, 5, 6, 7, 8 };
var evens = try filter(&numbers, [](n: *const i32): bool {
    return n.* % 2 = 0;
}, alloc);
defer alloc.free(evens);
-- evens: { 2, 4, 6, 8 }