summaryrefslogtreecommitdiff
path: root/devdocs/elisp/examples-of-catch.html
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
committerCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
commit754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch)
treef1190704f78f04a2b0b4c977d20fe96a828377f1 /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.html34
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 (&lt; i 10)
+ (let ((j 0))
+ (while (&lt; 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 &copy; 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>