Next: , Up: Nonlocal Exits   [Index]


F.6.1 catch and throw—Explicit Nonlocal Exits

Catch and Throw Concepts

The function throw performs a nonlocal exit on request. It is used inside a catch, and jumps back to that catch.

(defun foo-outer ()
  (catch 'foo
    (foo-inner)))

(defun foo-inner ()
  …
  (if x
      (throw 'foo t))
  …)

Listing F.2: Simple example of catch-throw

In the above example, the throw specifies ‘foo’, and the catch in foo-outer specifies the same symbol, so that catch is the applicable one.

Function: 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 except ‘nil’.

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 executed during the execution of ‘body’, specifying the same value ‘tag’, the catch form 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.

The throw form, if executed, 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 function throw finds the matching catch based on the first argument: it searches for a catch whose first argument is eq to the one specified in the throw. 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. The bindings are unbound, just as they are when these constructs exit normally. throw restores the buffer and position saved by save-excursion, and the narrowing status saved by save-restriction. It also runs any cleanups established with the unwind-protect special form when it exits that form.

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.


Next: Errors—Unintentional Nonlocal Exits, Up: Nonlocal Exits   [Index]