Errors
E# treats errors as values. In-language flow uses Result<T, E> and ?; try/catch is reserved for
the BCL boundary.
Result<T, E>
Section titled “Result<T, E>”Result<T, E> is a built-in type: either ok(value) or error(value). The error type is user-chosen,
commonly a choice. Inspect it with .IsOk / .IsError, .Value / .Error, or the combinators .Map,
.MapErr, .Bind, .Match, .Inspect, .InspectErr, .UnwrapOr, .UnwrapOrElse, .Unwrap,
.UnwrapErr. The constructors ok(...) / error(...) are expressions; inside error(...) the .case
dot-shorthand resolves against a known error type.
The ? operator
Section titled “The ? operator”expr? unwraps a Result: it yields the ok value, or returns the error from the enclosing function. It
is a real expression operator, valid anywhere an expression appears:
let user = findUser(id)? // in a letreturn ok(parse(raw)? + 1) // in a returnwrite(parse(raw)?) // as an argumentvalidate(input)? // bare statement — propagate on error, else continueThe enclosing function’s error type shall be compatible with the propagated error; this is why a module
tends to share one error choice. The spelling expr?.member is parsed as the null-conditional operator,
not unwrap-then-access; parenthesise ((expr?).member) or bind with a let.
Optionals vs. Result
Section titled “Optionals vs. Result”| Tool | Meaning |
|---|---|
T? | optional presence — “there might not be a value” |
Result<T, E> | a fallible operation — “this can fail, and here is why” |
See Types → nullable.
let-else
Section titled “let-else”A let … else guard binds a value or diverges; the else block shall leave the scope. Grammar and rules
are in Statements.
try / catch boundary
Section titled “try / catch boundary”The BCL throws; catch at that seam and translate into a Result, then return to value-based flow. There is
no finally — use defer inside the try. throw with no operand
rethrows and is valid only inside a catch. The three catch shapes and grammar are in
Statements → try / catch / throw. The rule of thumb: catch
exceptions at the edge, pass values everywhere else.