Common Lisp the Language, 2nd Edition

Next: Iteration Up: Control Structure Previous: Conditionals

# 7.7. Blocks and Exits

The `block` and `return-from` constructs provide a structured lexical non-local exit facility. At any point lexically within a `block` construct, a `return-from` with the same name may be used to perform an immediate transfer of control that exits from the `block`. In the most common cases this mechanism is more efficient than the dynamic non-local exit facility provided by `catch` and `throw`, described in section 7.11.

[Special Form]
`block name {form}*`

The `block` construct executes each form from left to right, returning whatever is returned by the last form. If, however, a `return` or `return-from` form that specifies the same name is executed during the execution of some form, then the results specified by the `return` or `return-from` are immediately returned as the value of the `block` construct, and execution proceeds as if the `block` had terminated normally. In this, `block` differs from `progn`; the `progn` construct has nothing to do with `return`.

The name is not evaluated; it must be a symbol. The scope of the name is lexical; only a `return` or `return-from` textually contained in some form can exit from the block. The extent of the name is dynamic. Therefore it is only possible to exit from a given run-time incarnation of a block once, either normally or by explicit return.

The `defun` form implicitly puts a `block` around the body of the function defined; the `block` has the same name as the function. Therefore one may use `return-from` to return prematurely from a function defined by `defun`.

The lexical scoping of the block name is fully general and has consequences that may be surprising to users and implementors of other Lisp systems. For example, the `return-from` in the following example actually does work in Common Lisp as one might expect:

    (block loser
       (catch 'stuff
          (mapcar #'(lambda (x) (if (numberp x)
                                    (hairyfun x)
                                    (return-from loser nil)))
                  items)))

Depending on the situation, a `return` in Common Lisp may not be simple. A `return` can break up catchers if necessary to get to the block in question. It is possible for a ``closure'' created by `function` for a lambda-expression to refer to a block name as long as the name is lexically apparent.

[Special Form]
`return-from name [result]`

`return-from` is used to return from a `block` or from such constructs as `do` and `prog` that implicitly establish a `block`. The name is not evaluated and must be a symbol. A `block` construct with the same name must lexically enclose the occurrence of `return-from`; whatever the evaluation of result produces is immediately returned from the block. (If the result form is omitted, it defaults to `nil`. As a matter of style, this form ought to be used to indicate that the particular value returned doesn't matter.)

The `return-from` form itself never returns and cannot have a value; it causes results to be returned from a `block` construct. If the evaluation of result produces multiple values, those multiple values are returned by the construct exited.

[Macro]
`return` `[result]`

`(return form)` is identical in meaning to `(return-from `nil` form)`; it returns from a block named `nil`. Blocks established implicitly by iteration constructs such as `do` are named `nil`, so that `return` will exit properly from such a construct.

Next: Iteration Up: Control Structure Previous: Conditionals