Emacs Lisp: Exit Loop/Function, catch/throw

By Xah Lee. Date: . Last updated: .

To exit a loop or function in elisp:

Exit a Function

To exit a function, put throw 'tagname value at the place you want to exit, and wrap your function body with a catch 'tagname for the target exit position.

Here's example.

(defun test-exit-f ()
  "example. using catch/throw to exit function"
  (interactive)
  (catch 'aaa
    (if (y-or-n-p "exit?")
        (progn
          (message "existing")
          (throw 'aaa 3) ; if yes, exit right away, return 3 to catch
          )
      (progn ; else, go on
        (message "went on")
        4 ; return 4
        ))))

Exit by Error

You can 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 map

You can also use throw and catch to exit a map or loop.

(catch 'tagname body) → evaluates body and return body's last expression, but if body contains (throw …) and it is called, return the value throw passes.

(throw tagName passValue) → jump to a outer (catch 'tagName) and continue there, passing the value of passValue to it. Both tagName passValue are evaluated.

(setq myList [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)))
   myList)
  nil
  )

(info "(elisp) Catch and Throw")

Exit a While Loop by Flag

Here's a sample of setting flag:

(let ((myList [0 1 2 3 4 5] )
      (foundFlag-p nil )
      (i 0))

  (while (and
          (not foundFlag-p)
          (<= i (length myList)))

    ;; if found, set foundFlag-p
    (when (equal (elt myList i) 3)
      (setq foundFlag-p t ))

    (message "value: %s" i)
    (setq i (1+ i))))
Like it? Buy Xah Emacs Tutorial. Thanks.

or, buy something from Best Keyboard for Emacs