Common Lisp the Language, 2nd Edition
Next: Generalized Restarts
Up: Survey of Concepts
Previous: Restart
Functions
One important feature that restart-case
(or
restart-bind
) offers that catch
does not is
the ability to reason about the available points to which control might
be transferred without actually attempting the transfer. One could, for
example, write
(ignore-errors (throw ...))
which is a sort of poor man’s variation of
(when (find-restart 'something)
(invoke-restart 'something))
but there is no way to use ignore-errors
and
throw
to simulate something like
(when (and (find-restart 'something)
(find-restart 'something-else))
(invoke-restart 'something))
or even just
(when (and (find-restart 'something)
(yes-or-no-p "Do something? "))
(invoke-restart 'something))
because the degree of inspectability that comes with simply writing
(ignore-errors (throw ...))
is too primitive-getting the desired information also forces transfer of control, perhaps at a time when it is not desirable.
Many programmers have previously evolved strategies like the following on a case-by-case basis:
(defvar *foo-tag-is-available* nil)
(defun fn-1 ()
(catch 'foo
(let ((*foo-tag-is-available* t))
... (fn-2) ...)))
(defun fn-2 ()
...
(if *foo-tag-is-available* (throw 'foo t))
...)
The facility provided by restart-case
and
find-restart
is intended to provide a standardized protocol
for this sort of information to be communicated between programs that
were developed independently so that individual variations from program
to program do not thwart the overall modularity and debuggability of
programs.
Another difference between the restart facility and the
catch
/throw
facility is that a
catch
with any given tag completely shadows any outer
pending catch
that uses the same tag. Because of the
presence of compute-restarts
, however, it is possible to
see shadowed restarts, which may be very useful in some situations
(particularly in an interactive debugger).
Next: Generalized Restarts
Up: Survey of Concepts
Previous: Restart
Functions
AI.Repository@cs.cmu.edu