Special Operator block

Syntax:

block name form* {result}*

Arguments and Values:

7.7.0 3name—a symbol.

form—a form.

7.9.2 11 7.9.2 12results—the values of the forms if a normal return occurs, or else, if an explicit return occurs, the values that were transferred.

Description:

7.7.0 2block establishes a block named name and then evaluates forms as an implicit progn.

If a \macref{return} or \specref{return-from} that specifies \param{name} is executed during the execution of some \param{form}, then the results specified by the \macref{return} or \specref{return-from} are immediately returned as the value of \specref{block}, and execution proceeds as if the \specref{block} had terminated normally. Only a \macref{return} or \specref{return-from} textually contained in some \param{form} can exit from the \specref{block}.

The special operators block and return-from work together to provide a structured, lexical, non-local exit facility. At any point lexically contained within forms, return-from can be used with the given name to return control and values from the block form, except when an intervening block with the same name has been established, in which case the outer block is shadowed by the inner one.

The block named name has lexical scope and dynamic extent.

It is only possible to exit from a given run-time incarnation of a \specref{block} once, either normally or by explicit return.

Once established, a block may only be exited once, whether by normal return or explicit return.

Barmar didn't think the following was really essential. I agree. -kmp 21-Dec-90 7.7.0 6 The fact that \param{name} is lexical has consequences that might be surprising to users and implementors. For example: \code (block loser (catch 'stuff (mapcar #'(lambda (x) (if (numberp x) (hairyfun x) (return-from loser \nil))) items))) \endcode A \macref{return} can break up catchers if necessary to get to the block in question. It is possible for a \term{closure} created by \specref{function} for a \term{lambda expression} to refer to a \specref{block} name as long as the name is lexically apparent.

Examples:

 (block empty) → NIL
 (block whocares (values 1 2) (values 3 4)) → 3, 4
 (let ((x 1)) 
   (block stop (setq x 2) (return-from stop) (setq x 3))
   x) → 2
 (block early (return-from early (values 1 2)) (values 3 4)) → 1, 2
 (block outer (block inner (return-from outer 1)) 2) → 1
 (block twin (block twin (return-from twin 1)) 2) → 2
 ;; Contrast behavior of this example with corresponding example of CATCH.
 (block b
   (flet ((b1 () (return-from b 1)))
     (block b (b1) (print 'unreachable))
     2)) → 1

Affected By:

None.

Exceptional Situations:

None.

See Also:

return, return-from, Section 3.1 (Evaluation)

Notes:

This seems random to me. -kmp \specref{block} differs from \specref{progn} in that \specref{progn} has nothing to do with \macref{return}.