Elisp: Exit Loop or Function (throw, catch)
Ways to Exit a Loop or Function
- Use
throw
to exit and gotocatch
. These are like “break”, “goto” in other programing languages. - Use
seq-some
to exit iterations. 〔see Elisp: Sequence Iteration, Conditional Exit〕 - Use
error
oruser-error
to signal a error and exit process.
💡 TIP: there is no break, exit, return keywords in emacs lisp.
catch
-
(catch tagSymbol body)
Evaluates body and return body's last expression, but if body contains
throw
with same tagSymbol, and it is called, return the value throw passes.tagSymbol is a Symbol.
throw
-
(throw tagSymbol passValue)
Jump to a outer
catch
of the same tagSymbol and continue there, passing the value of passValue to it. Both tagSymbol passValue are evaluated.;; example of exit a while loop ;; prints a random integer ;; if 5 comes up, exit (catch 'abc (while (setq xx (random 10)) (message "%s" xx) (when (eq 5 xx) (throw 'abc t))))
Exit a Function
Here is a example using throw to exit a function. Throw is like simulating the return statement in other langs.
;; demo using catch/throw to exit function. (defun xx-test-exit (x) "if x is greater than 5, return string yes, else return no" ;; here, throw is similar to the return in other langs (catch 'aaa (if (> x 5) (progn (throw 'aaa "yes")) (progn "no" )))) (string-equal (xx-test-exit 2) "no") (string-equal (xx-test-exit 6) "yes")
Exit by Error
Exit by calling
error
or
user-error
.
(defun test-exit-f () "example" (interactive) (if (y-or-n-p "invoke user-error to exit?") (user-error "Error, because: %s" "you said so!") (progn ; else, go on (message "went on") )))
Exit a Iteration or Loop
You can also use throw
to exit a loop.
💡 TIP:
you can also use seq-some
.
〔see Elisp: Sequence Iteration, Conditional Exit〕
;; demo using throw catch to exit a mapping (let ((xseq [0 1 2 3 4 5])) ;; map lambda onto a list. If value 3 is found, return 3, else nil (catch 'bbb (mapc (lambda (x) (message "%s" x) (when (equal x 3) (throw 'bbb x))) xseq) nil ))