Common Lisp the Language, 2nd Edition


next up previous contents index
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 up previous contents index
Next: Iteration Up: Control Structure Previous: Conditionals


AI.Repository@cs.cmu.edu