Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Errors

An error aborts the current top-level form: the machine unwinds, the REPL reports, and the next form starts fresh. Part I has already met the main kinds —

  • parse errors, including unbound variables, caught before evaluation starts;
  • type errors, a primitive applied to the wrong kind of value;
  • staging errors, violations of the staging discipline (Part II).
(cdr 'a)
;! type error in cdr: expected Tup, got Sym("a")

throw

(throw v) raises the value of v as an error with a first-class payload — any value, typically a symbol or a structured list saying what went wrong:

(throw 'out-of-cheese)
;! uncaught throw: 'out-of-cheese

The payload rides the unwind intact, which makes throw a signalling mechanism rather than just a panic: a program can throw structured data and something below can take it apart.

catch

The something below is catch. (catch e) evaluates e and returns a tagged list either way: (ok value) if no error escapes, (error payload) if one does — a result the caller can dispatch on with car and eq?:

(catch (+ 1 2))
;=> ('ok 3)
(catch (throw 'boom))
;=> ('error 'boom)
(catch (throw (cons 'unbound (cons 'x nil))))
;=> ('error ('unbound 'x))

A thrown payload arrives structurally. Any other error inside a catch — a type error, say — arrives with its report flattened into a single symbol:

(catch (car 5))
;=> ('error 'type error in car: expected Tup, got Cst(5))

catch exists for one caller: the Purple REPL loop, which wraps each evaluation in it so that a user error prints a message instead of killing the session, and so that a base environment can report an unbound variable loudly as (unbound . name) rather than returning a silent default. It is deliberately minimal — no handler argument, no filtering, no rethrow — and user code is expected to reach for the session-level error handling of Part IV rather than call it directly. The floor takes the same view of catch as of its other effects: provide the smallest primitive the layer above needs, and let the layer above build the ergonomics.