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))
We have a number of options available. In general, what you are looking for is a "nonlocal exit"; see (info "(elisp) Nonlocal Exits")
.
You can catch
/ throw
to exit the function with a value. See (info "(elisp) Catch and Throw")
for details.
example:
(defun my-func ()
"Simplistic `catch'/`throw' example."
(catch 'my-early-return
(when t
(throw 'my-early-return "this is the short-circuit result of catch"))
"this is the fallback result of catch"))
You can also use cl-block
and cl-return-from
(although you will need to require cl-lib
). See (info "(cl) Blocks and Exits")
for details.
example:
(eval-when-compile
(require 'cl-lib))
(defun my-func ()
"Simplistic `cl-block'/`cl-return-from' example."
(cl-block my-func
(when t
(cl-return-from my-func))
(1+ 42)))
We also have cl-defun
which has an implicit cl-block
with the same name as the function, so we can use the cl-block
style with less typing.
example:
(eval-when-compile
(require 'cl-lib))
(cl-defun my-func ()
"Simplistic `cl-defun' implicit block example."
(when t
(cl-return-from my-func)) ; `my-func' is an implicit block.
(+ 42 1))
In old Emacsen, specifically Emacs 24.2 and earlier, cl-defun
was provided as defun*
by the now-obsolete library cl.el
.
example:
(eval-when-compile
(require 'cl))
(defun* my-func ()
"Simplistic `defun*' implicit block example."
(when t
(return-from my-func)) ; `my-func' is an implicit block.
(+ 42 1))
Note, however, that in Emacsen that old you can instead install cl-lib
as a compatibility layer from GNU[-devel] ELPA:
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.