Learn
Errors
A function that can fail says so in its type. Ignoring that is a compile error, not a runtime one.
Fallible types
type MathError = | DivByZero
fn safe_div(a: i64, b: i64) -> i64 ! MathError {
if b == 0 {
fail(DivByZero)
}
a / b
}
i64 ! MathError is an i64 or a
MathError. Three ways to open it:
match safe_div(10, 0) { // handle both halves
Ok(v) -> print("{v}")
Err(e) -> print("caught: {e}")
}
let v = safe_div(10, 2) ?? 0 - 1 // take a default; the right side is lazy
fn caller() -> i64 ! MathError {
let v = try safe_div(10, 2) // propagate, and say so in the type
v * 2
}
What you cannot do is nothing. let _ = risky() is refused too —
a binding being unnamed says nothing about whether its failure was considered.
Panics
A panic is for a bug, not for a condition: an index out of range, a division
by zero, an expect on None. It prints a message and
exits 101 in every engine. Whether a stack trace follows depends on how the
program was run, and the specification says which engines print one.
No null
Something that may be absent is an Option[T], and the compiler
makes you open it before you can use what is inside.
let found: Option[i64] = m.get("k")
print("{found ?? 0}")