Status: Proposal OVERRIDE (version 2) accepted 12/91Issue: LOOP-NAMED-BLOCK-NIL
Reference: Draft 9.126
Category: CLARIFICATION
Edit History: Version 1, 22-Dec-91, Kim Barrett
Version 2, 26-Jan-92, Kim Barrett (clarification, per KMP)
Problem Description:
(Note: All section numbers are from Draft 9.126)
Regarding:
section 8.1.2.2, page 8-2, last paragraph in section
Expansion of the \macref{loop} macro produces an implicit block named \nil\
unless \loop{named} is supplied. Thus, \macref{return} and
\specref{return-from} can be used to return values from \macref{loop} or to
exit \macref{loop}.
section 8.1.2.6, End-Test Control, p8-15, first itemization
\itemitem{\bull} The \loop{until} construct executes any \loop{finally}
clause. Since \loop{thereis} uses the macro \macref{return} to terminate
iteration, any \loop{finally} clause that is supplied is not evaluated.
section 8.1.2.6, End-Test Control, p8-15, second itemization
\itemitem{\bull} The \loop{until} construct executes any \loop{finally}
clause. Since \loop{never} uses the macro \macref{return} to terminate
iteration, any \loop{finally} clause that is supplied is not evaluated.
In his review, Barmar noted "hmm..." in regard to this issue of not having a
NIL block get generated even when NAMED is used. He and KMP discussed it and
decided (based on examining the Lucid and Symbolics implementations) that the
intent was clear and they would let it go.
In processing other review comments of Barmar's, KMP noticed that these two
items refer specifically to RETURN (rather than RETURN-FROM) being generated.
This suggests one of the following two things:
(a) RETURN was not intended in the second two cases, and RETURN-FROM was
meant.
(b) RETURN was intended intended in the second two, and this exposes the fact
that the part about having no NIL block in the first case was wrong.
How shall we proceed in fixing this?
Proposal (LOOP-NAMED-BLOCK-NIL:OVERRIDE):
Clarify that if a NAMED clause appears in a LOOP form then no implicit NIL
block is established by the LOOP form. That is, confirm interpretation (a)
and reject interpretation (b) from the Problem Description.
Editorial Impact:
The two bulleted items mentioned in the problem description need to be changed
to refer to the special operator RETURN-FROM rather than the macro RETURN.
Rationale:
Gives the user greater control over the expansion of a LOOP form, permitting
its use in places where it might not be desirable if a NIL block were always
established.
Examples:
(loop named foo
'failure)
-> SUCCESS
Current Practice:
Apple MCL 2.0b3 and Lucid 4.0 do not introduce an implicit NIL block if a
NAMED clause is present in the LOOP form.
Symbolics LOOP always introduces a NIL block, in addition to any block
established for a NAMED clause.
Discussion:
Barrett:
I think (a) (RETURN-FROM was meant, rather than RETURN) is preferable. The
main use I've found for explicitly named blocks is to avoid accidentally
shadowing the intended receiver of a return-from when writing a wrapper
macro. If LOOP might always introduce a NIL block then you can't safely
write such macros in terms of LOOP forms.
GSB:
I'm not sure how much help this is; I'll try to explain the history behind
the current Symbolics implementation.
My personal preference is for NAMED to use the named block instead of
(rather than in addition to) a block named NIL. Now, at the time I
implemented the ANSI loop (and extensions) at Symbolics, I was under the
impression that NAMED was not part of ANSI. Maybe it had been dyked from
the standard, maybe it was in the process of being removed (there was this
minimalist pressure at the time). JonL, you remember anything about this?
I was basically working from the first draft that differed greatly from the
prior Lucid documentation.
Now, a semantic divergence occurred several years ago between the "NIL" and
other "MIT" loop sources, and the Symbolics Zetalisp loop source, because
someone (Me) got confused about the semantics of Zetalisp's named PROG. In
particular, I translated (prog name varlist ...) into roughly
(block name (let varlist (tagbody ...))). This is not a correct
translation: Zetalisp named prog establishes that block name IN ADDITION TO
a block named NIL. Therefore when I did NAMED (as an extension to ANSI), I
made it compatible with the existing (lisp machine) one, against my own
preferences, because it was only an extension and the incompatibility is
fairly subtle.