Next: Iteration, Previous: Conditionals, Up: Control Structure
Common Lisp blocks provide a non-local exit mechanism very
similar to catch
and throw
, with lexical scoping.
This package actually implements cl-block
in terms of catch
; however, the lexical scoping allows the
byte-compiler to omit the costly catch
step if the
body of the block does not actually cl-return-from
the block.
The forms are evaluated as if by a
progn
. However, if any of the forms execute(cl-return-from
name)
, they will jump out and return directly from thecl-block
form. Thecl-block
returns the result of the last form unless acl-return-from
occurs.The
cl-block
/cl-return-from
mechanism is quite similar to thecatch
/throw
mechanism. The main differences are that block names are unevaluated symbols, rather than forms (such as quoted symbols) that evaluate to a tag at run-time; and also that blocks are always lexically scoped. In a dynamically scopedcatch
, functions called from thecatch
body can alsothrow
to thecatch
. This is not an option forcl-block
, where thecl-return-from
referring to a block name must appear physically within the forms that make up the body of the block. They may not appear within other called functions, although they may appear within macro expansions orlambda
s in the body. Block names andcatch
names form independent name-spaces.In true Common Lisp,
defun
anddefmacro
surround the function or expander bodies with implicit blocks with the same name as the function or macro. This does not occur in Emacs Lisp, but this package providescl-defun
andcl-defmacro
forms, which do create the implicit block.The Common Lisp looping constructs defined by this package, such as
cl-loop
andcl-dolist
, also create implicit blocks just as in Common Lisp.Because they are implemented in terms of Emacs Lisp's
catch
andthrow
, blocks have the same overhead as actualcatch
constructs (roughly two function calls). However, the byte compiler will optimize away thecatch
if the block does not in fact contain anycl-return
orcl-return-from
calls that jump to it. This means thatcl-do
loops andcl-defun
functions that don't usecl-return
don't pay the overhead to support it.
This macro returns from the block named name, which must be an (unevaluated) symbol. If a result form is specified, it is evaluated to produce the result returned from the
block
. Otherwise,nil
is returned.
This macro is exactly like
(cl-return-from nil
result)
. Common Lisp loops likecl-do
andcl-dolist
implicitly enclose themselves innil
blocks.
This macro executes statements while allowing for control transfer to user-defined labels. Each element of labels-or-statements can be either a label (an integer or a symbol), or a cons-cell (a statement). This distinction is made before macroexpansion. Statements are executed in sequence, discarding any return value. Any statement can transfer control at any time to the statements that follow one of the labels with the special form
(go
label)
. Labels have lexical scope and dynamic extent.