diff options
Diffstat (limited to 'devdocs/elisp/catch-and-throw.html')
| -rw-r--r-- | devdocs/elisp/catch-and-throw.html | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/devdocs/elisp/catch-and-throw.html b/devdocs/elisp/catch-and-throw.html new file mode 100644 index 00000000..78c2f160 --- /dev/null +++ b/devdocs/elisp/catch-and-throw.html @@ -0,0 +1,25 @@ + <h4 class="subsection">Explicit Nonlocal Exits: catch and throw</h4> <p>Most control constructs affect only the flow of control within the construct itself. The function <code>throw</code> 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.) <code>throw</code> is used inside a <code>catch</code>, and jumps back to that <code>catch</code>. For example: </p> <div class="example"> <pre class="example">(defun foo-outer () + (catch 'foo + (foo-inner))) + +(defun foo-inner () + … + (if x + (throw 'foo t)) + …) +</pre> +</div> <p>The <code>throw</code> form, if executed, transfers control straight back to the corresponding <code>catch</code>, which returns immediately. The code following the <code>throw</code> is not executed. The second argument of <code>throw</code> is used as the return value of the <code>catch</code>. </p> <p>The function <code>throw</code> finds the matching <code>catch</code> based on the first argument: it searches for a <code>catch</code> whose first argument is <code>eq</code> to the one specified in the <code>throw</code>. If there is more than one applicable <code>catch</code>, the innermost one takes precedence. Thus, in the above example, the <code>throw</code> specifies <code>foo</code>, and the <code>catch</code> in <code>foo-outer</code> specifies the same symbol, so that <code>catch</code> is the applicable one (assuming there is no other matching <code>catch</code> in between). </p> <p>Executing <code>throw</code> exits all Lisp constructs up to the matching <code>catch</code>, including function calls. When binding constructs such as <code>let</code> or function calls are exited in this way, the bindings are unbound, just as they are when these constructs exit normally (see <a href="local-variables">Local Variables</a>). Likewise, <code>throw</code> restores the buffer and position saved by <code>save-excursion</code> (see <a href="excursions">Excursions</a>), and the narrowing status saved by <code>save-restriction</code>. It also runs any cleanups established with the <code>unwind-protect</code> special form when it exits that form (see <a href="cleanups">Cleanups</a>). </p> <p>The <code>throw</code> need not appear lexically within the <code>catch</code> that it jumps to. It can equally well be called from another function called within the <code>catch</code>. As long as the <code>throw</code> takes place chronologically after entry to the <code>catch</code>, and chronologically before exit from it, it has access to that <code>catch</code>. This is why <code>throw</code> can be used in commands such as <code>exit-recursive-edit</code> that throw back to the editor command loop (see <a href="recursive-editing">Recursive Editing</a>). </p> <blockquote> <p><b>Common Lisp note:</b> Most other versions of Lisp, including Common Lisp, have several ways of transferring control nonsequentially: <code>return</code>, <code>return-from</code>, and <code>go</code>, for example. Emacs Lisp has only <code>throw</code>. The <samp>cl-lib</samp> library provides versions of some of these. See <a href="https://www.gnu.org/software/emacs/manual/html_node/cl/Blocks-and-Exits.html#Blocks-and-Exits">Blocks and Exits</a> in <cite>Common Lisp Extensions</cite>. </p> +</blockquote> <dl> <dt id="catch">Special Form: <strong>catch</strong> <em>tag body…</em> +</dt> <dd> + <p><code>catch</code> establishes a return point for the <code>throw</code> function. The return point is distinguished from other such return points by <var>tag</var>, which may be any Lisp object except <code>nil</code>. The argument <var>tag</var> is evaluated normally before the return point is established. </p> <p>With the return point in effect, <code>catch</code> evaluates the forms of the <var>body</var> in textual order. If the forms execute normally (without error or nonlocal exit) the value of the last body form is returned from the <code>catch</code>. </p> <p>If a <code>throw</code> is executed during the execution of <var>body</var>, specifying the same value <var>tag</var>, the <code>catch</code> form exits immediately; the value it returns is whatever was specified as the second argument of <code>throw</code>. </p> +</dd> +</dl> <dl> <dt id="throw">Function: <strong>throw</strong> <em>tag value</em> +</dt> <dd> +<p>The purpose of <code>throw</code> is to return from a return point previously established with <code>catch</code>. The argument <var>tag</var> is used to choose among the various existing return points; it must be <code>eq</code> to the value specified in the <code>catch</code>. If multiple return points match <var>tag</var>, the innermost one is used. </p> <p>The argument <var>value</var> is used as the value to return from that <code>catch</code>. </p> <p>If no return point is in effect with tag <var>tag</var>, then a <code>no-catch</code> error is signaled with data <code>(<var>tag</var> <var>value</var>)</code>. </p> +</dd> +</dl><div class="_attribution"> + <p class="_attribution-p"> + Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc. <br>Licensed under the GNU GPL license.<br> + <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Catch-and-Throw.html" class="_attribution-link">https://www.gnu.org/software/emacs/manual/html_node/elisp/Catch-and-Throw.html</a> + </p> +</div> |
