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
   (lambda (x)
     (if …
       (progn (throw TAG VALUE) )
       (progn …)
 ‹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)))

(info "(elisp) Catch and Throw")