How do you return early from a function before it's ended? For example:
(defun my-func ()
"for example."
(unless something (return nil))
; continue as usual...
(+ 42 1))
Emacs Stack Exchange is a question and answer site for those using, extending or developing Emacs. It only takes a minute to sign up.
Sign up to join this communityWe have a number of options available.
You can catch
/ throw
to exit the function.
example:
(defun my-func ()
"thrown error"
(catch 'my-catch
(when t
(throw 'my-catch "always going to throw"))
(+ 42 1)))
You can also use block
and return-from
(although you will need to require cl-macs
)
example:
(require 'cl-macs)
(defun my-func ()
"block / return-from"
(block my-func
(when t
(return-from my-func))
(+ 42 1)))
We also have cl-defun
which has an implicit block
with the same name as the function, so we can do the block
style with less.
example:
(require 'cl-macs)
(cl-defun my-func ()
"cl-defun implicit block"
(when t
(return-from my-func)) ; my-func is an implicit block.
(+ 42 1)))
cl-defun
is also available as an alias defun*
which is defined in cl.el
so:
(require 'cl)
(defun* my-func ()
"defun* implicit block"
(when t
(return-from my-func)) ; my-func is an implicit block.
(+ 42 1)))
catch
/throw
is more idiomatic in elisp, as other approaches are ultimately implemented in terms of catch/throw. The elisp manual says: "Most other versions of Lisp, including Common Lisp, have several ways of transferring control nonsequentially: return
, return-from
, and go
, for example. Emacs Lisp has only throw
."
– phils
Jan 31 '15 at 5:28
In addition to what @EmacsFodder covered, just raise an error.
This will not help if the code is called within (dynamically, not lexically) the extent of error-handling constructs such as ignore-errors
or condition-case
, but otherwise it is a fine way to exit a function. It is in fact what is done most of the time.
(defun my-func ()
"..."
(unless something (error "Whoops!"))
; continue as usual...
(+ 42 1))
If you want to handle the error yourself then you can put the calling code (e.g. the call to something that ulimately calls my-func
) inside a condition-case
.
Again, this is what is done most of the time, at least as often as using catch
+ throw
. It all depends on what behavior you want.
catch
, unwind-protect
, condition-case
and the like are useful. There is a whole section of the Elisp manual devoted to nonlocal exits. (And there is nothing particularly kludgy about any of them, IMO.)
– Drew
Feb 1 '15 at 2:54