(lispref.info)Catch and Throw


Next: Examples of Catch Up: Nonlocal Exits

Explicit Nonlocal Exits: `catch' and `throw'
--------------------------------------------

   Most control constructs affect only the flow of control within the
construct itself.  The function `throw' is the exception to this rule
for of normal program execution: it performs a nonlocal exit on
request.  (There are other exceptions, but they are for error handling
only.)  `throw' is used inside a `catch', and jumps back to that
`catch'.  For example:

     (catch 'foo
       (progn
         ...
           (throw 'foo t)
         ...))

The `throw' transfers control straight back to the corresponding
`catch', which returns immediately.  The code following the `throw' is
not executed.  The second argument of `throw' is used as the return
value of the `catch'.

   The `throw' and the `catch' are matched through the first argument:
`throw' searches for a `catch' whose first argument is `eq' to the one
specified.  Thus, in the above example, the `throw' specifies `foo',
and the `catch' specifies the same symbol, so that `catch' is
applicable.  If there is more than one applicable `catch', the
innermost one takes precedence.

   All Lisp constructs between the `catch' and the `throw', including
function calls, are exited automatically along with the `catch'.  When
binding constructs such as `let' or function calls are exited in this
way, the bindings are unbound, just as they are when these constructs
are exited normally (Note: Local Variables.).  Likewise, the buffer
and position saved by `save-excursion' (Note: Excursions.) are
restored, and so is the narrowing status saved by `save-restriction'
and the window selection saved by `save-window-excursion' (Note: Window
Configurations.).  Any cleanups established with the `unwind-protect'
special form are executed if the `unwind-protect' is exited with a
`throw'.

   The `throw' need not appear lexically within the `catch' that it
jumps to.  It can equally well be called from another function called
within the `catch'.  As long as the `throw' takes place chronologically
after entry to the `catch', and chronologically before exit from it, it
has access to that `catch'.  This is why `throw' can be used in
commands such as `exit-recursive-edit' which throw back to the editor
command loop (Note: Recursive Editing.).

     Common Lisp note: most other versions of Lisp, including Common
     Lisp, have several ways of transferring control nonsequentially:
     `return', `return-from', and `go', for example.  Emacs Lisp has
     only `throw'.

 - Special Form: catch TAG BODY...
     `catch' establishes a return point for the `throw' function.  The
     return point is distinguished from other such return points by TAG,
     which may be any Lisp object.  The argument TAG is evaluated
     normally before the return point is established.

     With the return point in effect, the forms of the BODY are
     evaluated in textual order.  If the forms execute normally,
     without error or nonlocal exit, the value of the last body form is
     returned from the `catch'.

     If a `throw' is done within BODY specifying the same value TAG,
     the `catch' exits immediately; the value it returns is whatever
     was specified as the second argument of `throw'.

 - Function: throw TAG VALUE
     The purpose of `throw' is to return from a return point previously
     established with `catch'.  The argument TAG is used to choose
     among the various existing return points; it must be `eq' to the
     value specified in the `catch'.  If multiple return points match
     TAG, the innermost one is used.

     The argument VALUE is used as the value to return from that
     `catch'.

     If no return point is in effect with tag TAG, then a `no-catch'
     error is signaled with data `(TAG VALUE)'.


automatically generated by info2www