Copyright (C) 2000-2012 |
GNU Info (elisp)Catch and ThrowExplicit 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 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: (defun foo-outer () (catch 'foo (foo-inner))) (defun foo-inner () ... (if x (throw 'foo t)) ...) 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. Thus, 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 (assuming there is no other matching `catch' in between). 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 (Note: Local Variables). Likewise, `throw' restores the buffer and position saved by `save-excursion' (Note: Excursions), and the narrowing status saved by `save-restriction' and the window selection saved by `save-window-excursion' (Note: Window Configurations). It also runs any cleanups established with the `unwind-protect' special form when it exits that form (Note: 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 (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 except `nil'. 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 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'. 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 version 1.2.2.9 |