Conditionals
Control Structure
Iteration
Common Lisp blocks provide a non-local exit mechanism very
similar to catch
and throw
, but lexically rather than
dynamically scoped. This package actually implements block
in terms of catch
; however, the lexical scoping allows the
optimizing byte-compiler to omit the costly catch
step if the
body of the block does not actually return-from
the block.
progn
. However,
if any of the forms execute (return-from name)
,
they will jump out and return directly from the block
form.
The block
returns the result of the last form unless
a return-from
occurs.
The block
/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) which evaluate to a tag at run-time; and
also that blocks are lexically scoped whereas catch
/throw
are dynamically scoped. This means that functions called from the
body of a catch
can also throw
to the catch
,
but the 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 defun*
and defmacro*
forms which do create the implicit block.
The Common Lisp looping constructs defined by this package,
such as loop
and dolist
, also create implicit blocks
just as in Common Lisp.
Because they are implemented in terms of Emacs Lisp catch
and throw
, blocks have the same overhead as actual
catch
constructs (roughly two function calls). However,
Zawinski and Furuseth's optimizing byte compiler (standard in
Emacs 19) will optimize away the catch
if the block does
not in fact contain any return
or return-from
calls
that jump to it. This means that do
loops and defun*
functions which don't use return
don't pay the overhead to
support it.
block
.
Otherwise, nil
is returned.
(return-from nil result)
.
Common Lisp loops like do
and dolist
implicitly enclose
themselves in nil
blocks.