Common Lisp the Language, 2nd Edition

Next: Interactive Condition Handling Up: Survey of Concepts Previous: Comparison of Restarts

## 29.3.10. Generalized Restarts

`restart-case` is a mechanism that allows only imperative transfer of control for its associated restarts. `restart-case` is built on a lower-level mechanism called `restart-bind`, which does not force transfer of control.

`restart-bind` is to `restart-case` as `handler-bind` is to `handler-case`. The syntax is

    (restart-bind ((name function . options)) . body)

The body is executed in a dynamic context within which the function will be called whenever `(invoke-restart 'name)` is executed. The options are keyword-style and are used to pass information such as that provided with the `:report` keyword in `restart-case`.

A `restart-case` expands into a call to `restart-bind` where the function simply does an unconditional transfer of control to a particular body of code, passing along ``argument'' information in a structured way.

It is also possible to write restarts that do not transfer control. Such restarts may be useful in implementing various special commands for the debugger that are of interest only in certain situations. For example, one might imagine a situation where file space was exhausted and the following was done in an attempt to free space in directory `dir`:

    (restart-bind ((nil #'(lambda () (expunge-directory dir))
                        :report-function
                          #'(lambda (stream)
                              (format stream "Expunge ~A."
                                      (directory-namestring dir)))))
      (cerror "Try this file operation again."
              'directory-full :directory dir))

In this case, the debugger might be entered and the user could first perform the expunge (which would not transfer control from the debugger context) and then retry the file operation:

    Lisp> (open "FOO" :direction :output)
    Error: The directory PS:<JDOE> is full.
    To continue, type :CONTINUE followed by an option number:
     1: Try this file operation again.
     2: Expunge PS:<JDOE>.
     3: Return to Lisp Toplevel.
    Debug> :continue 2
    Expunging PS:<JDOE> ... 3 records freed.
    Debug> :continue 1
     => #<OUTPUT-STREAM "PS:<JDOE>FOO.LSP" 2323473>

Next: Interactive Condition Handling Up: Survey of Concepts Previous: Comparison of Restarts