Common Lisp the Language, 2nd Edition
In addition to anonymous restarts, one can have named restarts, which can be invoked
by name from within code. As a trivial example, one could write
(restart-case (invoke-restart 'foo 3) (foo (x) (+ x 1)))
to add 3 to 1, returning 4. This trivial example is conceptually analogous to writing:
(+ (catch 'something (throw 'something 3)) 1)
For a more realistic example, the code for the function symbol-value might signal an unbound variable error as follows:
(restart-case (error "The variable ~S is unbound." variable) (continue () :report (lambda (s) ;Argument s is a stream (format s "Retry getting the value of ~S." variable)) (symbol-value variable)) (use-value (value) :report (lambda (s) ;Argument s is a stream (format s "Specify a value of ~S to use this time." variable)) value) (store-value (value) :report (lambda (s) ;Argument s is a stream (format s "Specify a value of ~S to store and use." variable)) (setf (symbol-value variable) value) value))
If this were part of the implementation of symbol-value, then it would be possible for users to write a variety of automatic handlers for unbound variable errors. For example, to make unbound variables evaluate to themselves, one might write
(handler-bind ((unbound-variable #'(lambda (c) ;Argument c is a condition (when (find-restart 'use-value) (invoke-restart 'use-value (cell-error-name c)))))) body)