stop_or_call n, f: (Nat -> Nat), g: (Nat -> Nat) =
    if n <= 0:
        do 1
        do:
            m = n - 1
            assert m in Nat
            g (f m)

fact(n: Nat): Nat =
    stop_or_call n, fact, (r, ) -> r * n

assert fact(5) == 120

iterate(_, 0, x) = x
iterate(f, n: Int, x) = iterate f, n-1, f x

assert iterate((x -> x + 1), 5, 0) == 5
assert iterate((x -> x + "a"), 5, "b") == "baaaaa"

push! x: Str =
    res = ![]
    res.push! x
    for! [], a =>
        res.extend! push! a
    res

assert push!("a") == ["a"]
