diff options
| author | Craig Jennings <c@cjennings.net> | 2024-04-07 13:41:34 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2024-04-07 13:41:34 -0500 |
| commit | 754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch) | |
| tree | f1190704f78f04a2b0b4c977d20fe96a828377f1 /devdocs/elisp/examples-of-catch.html | |
new repository
Diffstat (limited to 'devdocs/elisp/examples-of-catch.html')
| -rw-r--r-- | devdocs/elisp/examples-of-catch.html | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/devdocs/elisp/examples-of-catch.html b/devdocs/elisp/examples-of-catch.html new file mode 100644 index 00000000..d10b0589 --- /dev/null +++ b/devdocs/elisp/examples-of-catch.html @@ -0,0 +1,34 @@ + <h4 class="subsection">Examples of catch and throw</h4> <p>One way to use <code>catch</code> and <code>throw</code> is to exit from a doubly nested loop. (In most languages, this would be done with a <code>goto</code>.) Here we compute <code>(foo <var>i</var> <var>j</var>)</code> for <var>i</var> and <var>j</var> varying from 0 to 9: </p> <div class="example"> <pre class="example">(defun search-foo () + (catch 'loop + (let ((i 0)) + (while (< i 10) + (let ((j 0)) + (while (< j 10) + (if (foo i j) + (throw 'loop (list i j))) + (setq j (1+ j)))) + (setq i (1+ i)))))) +</pre> +</div> <p>If <code>foo</code> ever returns non-<code>nil</code>, we stop immediately and return a list of <var>i</var> and <var>j</var>. If <code>foo</code> always returns <code>nil</code>, the <code>catch</code> returns normally, and the value is <code>nil</code>, since that is the result of the <code>while</code>. </p> <p>Here are two tricky examples, slightly different, showing two return points at once. First, two return points with the same tag, <code>hack</code>: </p> <div class="example"> <pre class="example">(defun catch2 (tag) + (catch tag + (throw 'hack 'yes))) +⇒ catch2 +</pre> + +<pre class="example">(catch 'hack + (print (catch2 'hack)) + 'no) +-| yes +⇒ no +</pre> +</div> <p>Since both return points have tags that match the <code>throw</code>, it goes to the inner one, the one established in <code>catch2</code>. Therefore, <code>catch2</code> returns normally with value <code>yes</code>, and this value is printed. Finally the second body form in the outer <code>catch</code>, which is <code>'no</code>, is evaluated and returned from the outer <code>catch</code>. </p> <p>Now let’s change the argument given to <code>catch2</code>: </p> <div class="example"> <pre class="example">(catch 'hack + (print (catch2 'quux)) + 'no) +⇒ yes +</pre> +</div> <p>We still have two return points, but this time only the outer one has the tag <code>hack</code>; the inner one has the tag <code>quux</code> instead. Therefore, <code>throw</code> makes the outer <code>catch</code> return the value <code>yes</code>. The function <code>print</code> is never called, and the body-form <code>'no</code> is never evaluated. </p><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/Examples-of-Catch.html" class="_attribution-link">https://www.gnu.org/software/emacs/manual/html_node/elisp/Examples-of-Catch.html</a> + </p> +</div> |
