Re: LOOP blows!
- From: Madhu <enometh@xxxxxxxx>
- Date: Fri, 08 Feb 2008 11:49:27 +0530
* Kaz Kylheku Wrote on Thu, 7 Feb 2008 21:03:21 -0800 (PST):
| On Feb 7, 7:38 pm, Madhu
|> 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).
This must considered merely to be an artifact of your implementation,
you should not make an inference on how LOOP *should* behave from this
behaviour.
|> * 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?
There are two `initializations' in execution of LOOP, [as I tried to make
clear].
One: INITIALLY. All variables are initialized at the beginning --- but
before staring the first iteration. the INITIALLY clause is executed
after this phase.
Two: At beginning of each iteration. All variables in the FOR clauses
are initialized in this phase.
(loop with x = 10 initially (princ x) repeat 2 do (dummy))
=> prints 10.
(loop for x = 10 initially (princ x) repeat 2 do (dummy))
=> prints NIL
ONLY WITH variables are initialized before start of first iteration. FOR
iterations are bound to NIL.
But this is already clear to you
|> 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 cited the reference to show it is initialized to (1 2 3) ONLY during
the beginning of the first iteration.
But the termination test for the 2nd for loop kicks in BEFORE that!
Which is why the loop is never entered.
| 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.
No no no! LOOP FOR X = '(1 2 3) AND Y IN X is just wrong syntax. It is
not allowed by LOOP. your mplementation is horrible if it lets it
through. The two `for' clauses being connected are different. the
second clause is a for-as-in-list clause.
The only reason it would terminate would be the same. INITIALLY: X NIL Y
NIL. The termination test passes, before the first iteration of the
loop (when the for-as-is-clause variable can be initialized) is even
entered.
|> 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.
That may be a fact, but I think it tells more on the implementors
ability/taste than the standard.
|> 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.
Yes, My mistake I meant (CAR XTEMP).
| 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.
But This was not even meant to be an accurate translation of your
[wrong]example. It was meant to illustrate a point. And it is easily
illustrated now :)
You said yourself that Y is meant ``capture the value of the list
expression once, and then step over /that/ list object, regardless of
what happens to the value of that original expression.''
Now, this happens but it happens BEFORE X is initialized to '(1 2 3) in
the for-as-then clause. It HAS to happen then, and not on the first
iteration, [it is this implausibility of this scenario i wished to show
in the DO* example, but no point continuing on a wrong example]
|
| (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.
Yes
--
Madhu
.
- Follow-Ups:
- Re: LOOP blows!
- From: Kaz Kylheku
- Re: LOOP blows!
- From: Madhu
- Re: LOOP blows!
- References:
- LOOP blows!
- From: Kaz Kylheku
- Re: LOOP blows!
- From: Maciej Katafiasz
- Re: LOOP blows!
- From: Kaz Kylheku
- Re: LOOP blows!
- From: Madhu
- Re: LOOP blows!
- From: Kaz Kylheku
- LOOP blows!
- Prev by Date: Re: LOOP blows!
- Next by Date: Re: How does functional programming attack the object oriented programming area?
- Previous by thread: Re: LOOP blows!
- Next by thread: Re: LOOP blows!
- Index(es):
Relevant Pages
- Re: LOOP blows!
... clauses appear in the source. ... This clause is not combined
with the ... Right, and ``People'' includes the ones implementing LOOP, apparently, ...
You must use your hidden list iteration variable to set up the ... (comp.lang.lisp) - Re: LOOP blows!
... At beginning of each iteration. ... All variables in the FOR clauses
... ] All variables are initialized in the loop prologue. ... Initialization
is not assignment! ... (comp.lang.lisp) - Re: how can you improve this function?
... iteration of a task a given number of times is the ... in the context of a for
loop the ... The repeat or do-while loops are ... If the user naturally thinks
"let's do that initialization, ... (comp.programming) - Loop for and behaviour
... must warn that I'm not a loop expert and all my loops were ... Summary of Variable
Initialization and Stepping Clauses ... The for and as constructs provide iteration
control clauses that ... (comp.lang.lisp) - 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)