Skip to content

Result and try

Propagating errors with try, terminating with match.

enum Result[T, E]:
case Ok(value: T)
case Err(error: E)
def read(ok: bool) -> Result[i32, bool]:
if ok:
return Ok(value=42)
else:
return Err(error=true)
def close(ok: bool) -> Result[None, bool]:
if ok:
return Ok(value=None)
else:
return Err(error=true)
def compute(ok: bool) -> Result[i32, bool]:
try close(true)
let value: i32 = try read(ok)
return Ok(value=value)
def main() -> i32:
let result: Result[i32, bool] = compute(true)
let code: i32 = match result:
Ok(value) => value
Err(error) => 1
return code

What’s worth noticing:

  • try close(true): try in statement position. The Ok payload here is None, so the value is discarded; an Err would cause compute to return early with the same Err.
  • let value: i32 = try read(ok): try in expression position. On Ok(v), evaluates to v. On Err(e), the function returns Err(error=e) immediately.
  • match result: is used at the top level in main: once you’re at the program boundary, try no longer makes sense (there’s no outer function to propagate to). Match terminates the chain.
  • The two try sites both produce Result[_, bool]: try requires the result’s E to match the surrounding function’s E.

For the helpers (is_ok, unwrap_or), see std.result.