Emacs Lisp: Ways to Exit/Break a Loop
Perm URL with updates: http://ergoemacs.org/emacs/elisp_break_loop.html
In many languages, there's “break” or “exit” keywords that you can use to exit a loop. In functional programing, usually you don't do loops or exit loops, but sometimes that's just what you need.
In elisp, to exit loop, you can either use a flag (i.e. set a variable to indicate whether to exit.), or use the built-in catch and throw.
Using a Flag
Here's a pseudo-code for using a flag:
(while (and (not found) (< i listLength)) … ; if found, set found (setq i (1+ i)) )
Here's a actual example using a flag:
(defun get-new-fpath (ξfPath moveFromToList) "Return a new file full path for ξfPath. moveFromToList is a alist." (let ((ξfoundResult nil) (ξi 0) (ξlen (length moveFromToList)) ) ;; compare to each moved dir. (while (and (not ξfoundResult) (< ξi ξlen)) (when (string-match (concat "\\`" (regexp-quote (car (elt moveFromToList ξi))) ) ξfPath ) (let ( (fromDir (car (elt moveFromToList ξi))) (toDir (cdr (elt moveFromToList ξi))) ) (setq ξfoundResult (concat toDir (substract-path ξfPath fromDir)) ) ) ) (setq ξi (1+ ξi) ) ) (if ξfoundResult ξfoundResult ξfPath ) ) )
Using throw and catch
Here's a pseudo-code of throw and catch.
(catch TAG (mapc (lambda (x) … (if … (progn (throw TAG VALUE) ) (progn …) ) ) ‹list› ) ‹value of catch if throw didn't occur› )
Here's a example using throw and catch.
(defun xahsite-url-is-xah-website-p (myURL) "Returns t if MYURL contains a xah domain name, else nil. See: `xahsite-domain-names'." (catch 'myloop (mapc (lambda (x) (when (string-match-p (format "\\`http://\\(www\\.\\)*%s\.*/*" (regexp-quote x)) myURL) (throw 'myloop t))) (xahsite-domain-names)) nil ) )