Control Flow & Errors
Tao has one if, one switch, one loop, one leave — and it reports
errors by value, not by exception.
if
if is an expression. Parentheses around the condition are optional, and
else if chains naturally. Without an else, a false condition yields
None.
if x { 1 } else { 2 }
if False { 1 } else if True { 3 } else { 2 } // 3
switch
switch is an expression. Arms match the value with ==; the optional
else arm catches everything else. Without a match, the result is None.
switch n {
1 => 100
2 => 200
else => -1
}
loop and leave
loop repeats forever. leave exits the innermost loop; using it outside a
loop is an error.
let mut i = 0
loop {
if i == 3 { leave }
i = i + 1
}
return
return expr returns from the enclosing function. Without an explicit
return, a function’s body evaluates to its last statement.
fun sign(n) {
if n < 0 { return -1 }
if n > 0 { return 1 }
0
}
Errors as values
Functions that can fail return a [val, err] list: the value, and an error
that is None on success.
fun readFile(path) {
if path == "" { return [None, "empty path"] }
return ["content", None]
}
let a, b = ...
Unpack the pair by hand:
let val, err = readFile("x")
if err != None { "failed" } else { val }
try
try expr unwraps a [val, err] pair: it yields the value when err is
None, otherwise it returns the error from the current function.
fun process() {
let content = try readFile("")
content
}
try may only appear inside a function, and the wrapped expression must
evaluate to a two-element list.