Error handling and continuations

Error handling and continuations

Arc provides several operations for error handling and non-linear control flow. Since Arc's control flow mechanisms are built on top of MzScheme, see the MzScheme manual on exceptions and control flow for details.

Arc's simplest mechanism for non-linear control flow is catch and throw. This allows execution to jump back to the catch expression, for example to exit a loop early.

arc> (catch (each x '(2 4 6 9 10 12) (prn "Examining " x) (if (odd x) (throw x))))
Examining 2
Examining 4
Examining 6
Examining 9
9

Arc also provides access to MzScheme's exception mechanism, which provides a way to trap errors or raise error.

The ccc function is equivalent to Scheme's call-with-current-continuation (often abbreviated as call/cc). Continuations are extremely powerful; for details see Teach Yourself Scheme in Fixnum Days, Chapter 20 of "On Lisp", Call with Current Continuation Patterns, or Advanced Scheme Techniques. In MzScheme, continuations are relatively expensive if the call stack is deep since capturing a continuation copies the stack.

point name [body ...]
Creates a 'throw' function called name and executes body. If name is executed within body, that value will be returned from point. Otherwise, point has no effect and the value from body will be returned.
>(+ 10 (point throw (+ 20 (throw 3) 30)))
13
catch body
Executes body and catches any value passed to throw. This is the same as point with the throw function's name predefined.
>(+ 10 (catch (+ 20 (throw 3) 30)))
13
ccc procedure
Packages up the current continuation into an 'escape procedure' and passes it to the procedure. Equivalent to Scheme's call/cc or call-with-current-continuation.
>(ccc (fn (ep) (ep "bailout value") 42))
"bailout value"
protect during-procedure after-procedure
Uses Scheme's dynamic-wind to ensure that after-procedure is executed whenever during-procedure exits.
>(protect (fn () (/ 1 0))
    (fn () (prn "after")))
after
Error: /: division by zero

after during-body [after-body ...]
Ensures that after-body executes whenever during-body exits.
details exception
Returns the message associated with an exception.
>(on-err (fn (ex) (details ex)) (err "boo"))
Error: boo

err string ...
Raises an exception with the given text.
>(err "Failure" 42)
Error: Failure 42

on-err err-proc proc
Executes proc. Calls err-proc if an exception occurs in proc. The exception is passed to err-proc
>(on-err (fn (ex) (string "caught " (details ex)))
          (fn () (/ 1 0)))
"caught /: division by zero"
errsafe expr
Executes expr, returning nil if an error occurs.
>(errsafe (/ 1 2))
1/2
>(errsafe (/ 1 0))
nil

Copyright 2008 Ken Shirriff.