Go to the previous, next section.
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 (see section Local Variables).
Likewise, the buffer and position saved by save-excursion
(see section Excursions) are restored, and so is the narrowing status
saved by save-restriction and the window selection saved by
save-window-excursion (see section 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 (see section Recursive Editing).
Common Lisp note: most other versions of Lisp, including Common Lisp, have several ways of transferring control nonsequentially:return,return-from, andgo, for example. Emacs Lisp has onlythrow.
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.
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).
Go to the previous, next section.