Next: Examples of Catch, Previous: Nonlocal Exits, Up: Nonlocal Exits [Contents][Index]
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 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.
Executing throw
exits all Lisp constructs up to the matching
catch
, including function calls. 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 exit normally
(see Local Variables). Likewise, throw
restores the buffer
and position saved by save-excursion
(see Excursions), and
the narrowing status saved by save-restriction
and the window
selection saved by save-window-excursion
(see Window Configurations). It also runs any cleanups established with the
unwind-protect
special form when it exits that form
(see Cleanups).
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
that throw back to the editor command loop (see 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. SXEmacs Lisp has onlythrow
.
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, catch
evaluates the forms of the
body 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)
.
Next: Examples of Catch, Previous: Nonlocal Exits, Up: Nonlocal Exits [Contents][Index]