;; One fn, several arities: the number of arguments picks one (decision 139). struct Grain kind: i32 ;; One arity calling another. fn is-empty-cell (g: Grain) -> bool g.kind == 0 (r: i32, c: i32) -> bool is-empty-cell(Grain{.kind r * c}) ;; One-line arities. fn area (w: i32) -> i32 = w * w (w: i32, h: i32) -> i32 = w * h (w: i32, h: i32, d: i32) -> i32 area(w, h) * d ;; A generic arity beside another, each with its own where clause. fn pick (x: $t) -> $t x (x: $t, y: $t, first: bool) -> $t where is-ordered($t) if first then min(x, y) else max(x, y) ;; An arity that recurses on itself and one that calls it. fn count (n: i32) -> i32 count(n, 0) (n: i32, acc: i32) -> i32 if n == 0 then acc else count(n - 1, acc + n) ;; defer runs per arity. fn noisy (a: i32) -> i32 defer println("leaving noisy/1") a (a: i32, b: i32) -> i32 defer println("leaving noisy/2") a + b ;; Untyped arities take dyn arguments, and the count still picks. fn scale (x) x * 10 (x, y) x * y fn apply(f: Fn(i32) -> i32, x: i32) -> i32 f(x) fn main() println(is-empty-cell(Grain{.kind 0})) println(is-empty-cell(Grain{.kind 2})) println(is-empty-cell(3, 0)) println(is-empty-cell(3, 4)) println(area(3)) println(area(3, 4)) println(area(3, 4, 5)) println(pick(7)) println(pick(1.5, 2.5, false)) println(pick(3, 9, true)) println(count(10)) println(noisy(1)) println(noisy(1, 2)) println(scale(4)) println(scale(2.5, 2)) ;; A wanted Fn type names the arity, so the name picks that version. println(apply(area, 6)) println(apply(fn(x) => area(x, 2), 6))