← All examples

An operator as a value

op +, handed wherever a function goes.

operator_values.zg
# An operator as a value (owner, 2026-09-29): `op +`, handed wherever a function goes. Its type
# comes from where it goes. `op -` subtracts; negation is `op neg`. A custom operator's operands
# are lent, so `op dot` is a fn[lent Vec, lent Vec] -> bin64.
struct Vec { x: bin64, y: bin64 }
op dot ['a': Vec, 'b': Vec] -> bin64 { return 'a'.x times 'b'.x plus 'a'.y times 'b'.y; }
fn fold [lent 'xs': list[int32], 'start': int32, 'f': fn[int32, int32] -> int32] -> int32 {
    let mut 'acc' := 'start';
    for 'x' in lend 'xs' { change 'acc' = 'f'['acc', 'x']; }
    return 'acc';
}
fn apply1 ['v': int32, 'f': fn[int32] -> int32] -> int32 { return 'f'['v']; }
fn test2 ['a': int32, 'b': int32, 'f': fn[int32, int32] -> bool] -> bool { return 'f'['a', 'b']; }
fn both [lent 'a': Vec, lent 'b': Vec, 'f': fn[lent Vec, lent Vec] -> bin64] -> bin64 { return 'f'[lend 'a', lend 'b']; }
MAIN {
    let 'xs': list[int32] = [1, 2, 3, 4];
    let 'sum' := fold[lend 'xs', 0, op plus];
    let 'product' := fold[lend 'xs', 1, op times];
    let 'down' := fold[lend 'xs', 0, op minus];
    let 'n' := apply1[5, op neg];
    let 'le' := test2[3, 3, op at_most ];
    let 'f': fn[int32, int32] -> int32 = op mod.floor;
    let 'm' := 'f'[-7, 3];
    let 'u' := Vec[x = 1.0, y = 2.0];
    let 'v' := Vec[x = 3.0, y = 4.0];
    let 'd' := both[lend 'u', lend 'v', op dot];
    std::print.useful['sum', " ", 'product', " ", 'down', " ", 'n', " ", 'le', " ", 'm', " ", 'd', newln];
}
Output
10 24 -10 -5 true 2 11