Next: Iteration, Previous: Conditionals, Up: Control Structure [Contents][Index]
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 the cl-block
form.
The cl-block
returns the result of the last form unless
a cl-return-from
occurs.
The cl-block
/cl-return-from
mechanism is quite similar to
the catch
/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 scoped catch
, functions called from the
catch
body can also throw
to the catch
. This
is not an option for cl-block
, where
the cl-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 or lambda
s in the body. Block
names and catch
names form independent name-spaces.
In true Common Lisp, defun
and defmacro
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 provides cl-defun
and cl-defmacro
forms, which do create the implicit block.
The Common Lisp looping constructs defined by this package,
such as cl-loop
and cl-dolist
, also create implicit blocks
just as in Common Lisp.
Because they are implemented in terms of Emacs Lisp’s catch
and throw
, blocks have the same overhead as actual
catch
constructs (roughly two function calls). However,
the byte compiler will optimize away the catch
if the block does
not in fact contain any cl-return
or cl-return-from
calls
that jump to it. This means that cl-do
loops and cl-defun
functions that don’t use cl-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 like cl-do
and cl-dolist
implicitly enclose
themselves in nil
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.
Next: Iteration, Previous: Conditionals, Up: Control Structure [Contents][Index]