;; One name, several versions: the number of arguments picks one (decision 135a). struct Grain kind: i32 fn is-empty-cell(g: Grain) -> bool g.kind == 0 ;; One version calling another. fn is-empty-cell(r: i32, c: i32) -> bool is-empty-cell(Grain{.kind r * c}) fn area(w: i32) -> i32 w * w fn area(w: i32, h: i32) -> i32 w * h fn area(w: i32, h: i32, d: i32) -> i32 area(w, h) * d ;; A generic version beside a plain one. fn pick(x: $t) -> $t x fn pick(x: $t, y: $t, first: bool) -> $t if first then x else y ;; A version that recurses on itself and calls the other. fn count(n: i32) -> i32 count(n, 0) fn count(n: i32, acc: i32) -> i32 if n == 0 then acc else count(n - 1, acc + n) ;; defer runs per version. fn noisy(a: i32) -> i32 defer println("leaving noisy/1") a fn noisy(a: i32, b: i32) -> i32 defer println("leaving noisy/2") a + b ;; Untyped versions take dyn arguments, and the count still picks. fn scale(x) x * 10 fn scale(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("a", "b", 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))