Re: LOOP blows!



On Feb 7, 7:38 pm, Madhu <enom...@xxxxxxxx> wrote:
If you wanted this to return '(1 2 3) you should have written:

 (loop with x = '(1 2 3) for y in x collect y)

But the point is that

(loop for x = '(1 2 3) for y in x collect y)

/does/ return (1 2 3) for me. I suspected that this is the cause of
the problem, which is why I presented that test case. (Though I
fumbled with that spurious DO).

 * 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."

So X is initialized to NIL before entering entering the first
iteration.

Indeed yes, so what?

The first for clause will never terminate.  The second for clause
terminates when there are no more elements to iterate over, as per
6.1.2.2 above when the list it is iterating over is empty.

X isn't the empty list any longer, because the first clause, FOR X =
'(1 2 3), assigns a value to X. This clause is not combined with the
second FOR Y clause using AND, so they do not work in parallel.

I understand that X is a local variable that starts out NIL. The first
FOR must change that by giving it a value.

Now, if I had

FOR X = '(1 2 3) AND Y IN X

then you would have a case. Now they are parallel, and so Y iterates
using the value of X that existed before the assignment of '(1 2 3),
the initial NIL. Thus the FOR Y IN clause instantly terminates and the
loop is dead on arrival.

I'd like to emphasise that there is no ambiguity in LOOP, the perceived
ambiguity comes from people expecting some behaviour without
understanding the well specified execution model.

Right, and ``People'' includes the ones implementing LOOP, apparently,
which is why we are getting different answers for some perfectly
innocuous code that ought to be portable.

It looks like LOOP is harder to get right than a lot of other parts of
Common Lisp! LOOP is historically a source of portability bugs.

--
Madhu

PS: If your goal was to return (1 2 3) you should not even start
considering this form of LOOP.

Even when what you wrote is translated to
DO* (do* ((x '(1 2 3) '(1 2 3))
       (xtemp x (cdr xtemp))
       (y (car x))

This is not how FOR IN works. It captures the value of the list
expression once, and then steps over /that/ list object, regardless of
what happens to the value of that original expression.

What you want above is:

(Y (CAR XTEMP))

You must use your hidden list iteration variable to set up the
successive values for Y, not make repeated references to the X
variable.

The logic you are describing has no hope of working; it's just
extracting (CAR X) on every iteration, and X doesn't change.

       (ret))
      ((null xtemp) (reverse ret))

See, why are you using the hidden iteration variable XTEMP to figure
out when the list iteration ends, but using (CAR X) to actually pull
out the value?

The logic is inconsistent.

   (push y ret))
all you can hope is for (1 1 1)

Nope. For instance:

(let ((list '(1 2 3)))
(loop for x in list collecting x do pop list))

should still produce (1 2 3), even though LIST changes throughout the
loop. The x variable iterates over the object that was initially
produced by LIST.
.



Relevant Pages

  • Re: LOOP blows!
    ... The order of initialization follows the ... There are two `initializations' in execution of LOOP, ... before staring the first iteration. ... |> The first for clause will never terminate. ...
    (comp.lang.lisp)
  • Re: for-else
    ... So I may like something similar for Python 3.x (or the removal of the ...   else: ... keeps the same name as the corresponding clause on the while loop. ...
    (comp.lang.python)
  • Re: LOOP blows!
    ... My understanding of the LOOP specification is that your expectation is ... Even if the FOR Y = X clause were to work by stepping a hidden integer ... and evaluating at every iteration to pull out the ... The problem with these implementations that return NIL is that they ...
    (comp.lang.lisp)
  • Re: The LOOP macro (was Re: Be afraid of XML)
    ... >> the finally clause. ... > "A loop macro form expands into a form containing ONE OR MORE BINDINGS ... > "The LOOP EPILOGUE CONTAINS forms that are executed after iteration ...
    (comp.lang.lisp)
  • Re: Do loops and omit a couple of iterations?
    ... but that affects every iteration. ... contents of the loop in an If...Then clause like this: ... Dim i as integer ... is to use a Select Case clause. ...
    (microsoft.public.word.vba.general)