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

Kaz Kylheku kaz at kylheku.com
Mon Oct 18 09:32:30 PDT 2010


On Mon, 18 Oct 2010 05:56:47 -0600 (MDT), Gary Byers <gb at clozure.com>
wrote:
> On Sun, 17 Oct 2010, Kaz Kylheku wrote:
>> Look at that! CLISP's loop assiduously performs
>> all the assignments, prior to the first iteration,
>> and only then evaluates the termination conditions
>> associated with the clauses prior to the loop
>> body.
> 
> No it doesn't.  If you don't believe me, macroexpand your
> example in CLISP and look at what actually happens.

You are right. The behavior differs based on the nature of the
forms involved.

For instance:

[32]> (loop for x in nil for y = m2 finally (return y))
NIL
[33]> (loop for x in nil for y = 2 finally (return y))
2
[34]> m2
2
[35]> m1
nil

(m1 and m2 happen to be symbol macros denoting function
call forms, which may not matter).

It looks like CLISP moved the assignment ahead of the
termination test because of Y being initialized with a constant,
which being what it is, cannot depend on any of the other
initializations.

But in the real code I don't have such a trivial constant;
I think I have not uncovered the real root cause of the
portability issue.

Furthermore, I am seeing a problem problem in which
the list being walked isn't empty (a stepping issue, not
an initialization problem).

> that your model will remain inaccurate.

Would it be fair to say:

The de-facto correct model (say, by implementation popularity)
seems to be that the iteration control clauses are somewhat
like statements and are performed in order, and that includes
triggering early termination, pre-empting subsequent
termination clauses (this not being spelled out in the
spec). Termination testing is not factored out into a separate
termination testing phase.

Furthermore, if any initializations are skipped by an
earlier termination tests, the values of those variables
are unspecified.

CLISP may be implementing that model, but changing some
aspects of it by moving things around when it seems
innocuous to do so that it in those cases it seems as
like a different model.

Certainly, the treatment of the y = 2 versus
y = m2 above is inconsistent. The difference is allowed
by a model which allows y to have any value at all if its
initialization is skipped.




More information about the Openmcl-devel mailing list