Exceptions are a special kind of effect: they do not resume. This is a form of early return from a function.

Exceptions can be of any type and are raised with the throw keyword.

The caller can handle such exceptions with the catch clause in a do {} block.

The value returned by the do {} block will be the value returned by the catch clause that handled the exception.

NB: Unhandled exceptions (like any other effects) are propagated to the runtime environment and crash the process.

func main(pub args: list<string>) -> @ok {
  err := do {
    throw (@error, @not_implemented);
  catch (@error, reason) {

  err = @not_implemented;

  throw @will_crash;



Throw expression

<throw-expression> :=
    "throw" <expression>

Exception catching

<do-expression> :=
    "do" "{" <proposition>+ "}"

<do-expression-clause> :=
    | <do-expression-catch>
    | <do-expression-intercept>

<do-expression-catch> :=
    "catch" <pattern> "{"