[Openmcl-devel] LOOP parallel for/as termination eval order issue.

Kaz Kylheku kaz at kylheku.com
Sun Oct 17 11:12:59 PDT 2010


Hi all,

The following for returns nil in CCL and Allegro, but (1 2 3) in 
Clisp.

(loop for x in nil and y = '(1 2 3) then (cdr y) finally (return y))

My expectation is that the CLISP behavior is right, because
X and Y ought to be initialized in parallel to NIL and (1 2 3)
respectively. Only then should the loop termination test kick in
due to X having run out of items. The FINALLY clause must not
see a nil value of Y.

The Hyperspec of course says that a for-as-in-list causes
termination when the list of items is exhausted. That
much is perfectly clear:

   6.1.2.1.2 The for-as-in-list subclause

   [...] The for or as construct causes termination when the end of
   the list is reached.

The question is when is this termination evaluated? The answer is 
here:

   6.1.2.1 Iteration Control

   [...] When iteration control clauses are used in a loop, the
   corresponding termination tests in the loop body are evaluated
   before any other loop body code is executed.

I.e. iteration control clauses have corresponding termination
tests. For instance "for x in list" has a corresponding termination
test whose logic is "if (endp x) then terminate".

Furthermore, where do these implicit termination tests live?
They are ``in the loop body'', placed prior to the evaluation
of other loop body code.

I.e. LOOP does not evaluate termination tests in the variable
initialization and stepping, but in the body.

Furthermore, there is this:

   6.1.1.6 Order of Execution

   [...]
   * All variables are initialized first, regardless of where the 
establishing
   clauses appear in the source. The order of initialization follows
   the order of these clauses.

   [...]
   * Iteration control clauses implicitly perform the following 
actions:

      -- initialize variables;

      -- step variables, generally between each execution of the loop 
body;

      -- perform termination tests, generally just before the 
execution
      of the loop body.


When major implementations get stuff like this wrong, no wonder
Lispers eschew LOOP (or include their own LOOP macro in the
code base).




More information about the Openmcl-devel mailing list