Re: LOOP blows!



* Kaz Kylheku Wrote on Thu, 7 Feb 2008 17:48:59 -0800 (PST):
| Nope, works on my machine. Your LOOP is obviously broken. :)
|
| Does this return (1 2 3)?
|
| (loop for x = '(1 2 3) for y in x do collect y)

Your LOOP fu is lacking. 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)

Lets look at what you wrote:

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

There are two for clauses: the first one is a

"6.1.2.1.4 The for-as-equals-then subclause"

for-as-equals-then::= var [type-spec] = form1 [then form2]

"In the for-as-equals-then subclause the for or as construct initializes
the variable var by setting it to the result of evaluating form1 on the
first iteration, then setting it to the result of evaluating form2 on
the second and subsequent iterations. If form2 is omitted, the
construct uses form1 on the second and subsequent iterations. The loop
keywords = and then serve as valid prepositions in this syntax. This
construct does not provide any termination tests."

So X will get initialized to '(1 2 3) at the begining of each iteration.
However BEFORE the first iteration it is bound to NIL. [For example See
(loop for a = 10 initially (princ x) repeat 2 do (princ ".."))]

The second is for clause is a

"6.1.2.1.2 The for-as-in-list subclause"

for-as-in-list::= var [type-spec] in form1 [by step-fun]

"In the for-as-in-list subclause, the for or as construct iterates over
the contents of a list. It checks for the end of the list as if by
using endp. The variable var is bound to the successive elements of the
list in form1 before each iteration. At the end of each iteration, the
function step-fun is applied to the list; the default value for
step-fun is cdr. The loop keywords in and by serve as valid
prepositions in this syntax. The for or as construct causes termination
when the end of the list is reached."

So Y will be initialized to successive elements of X before each
iteration. But what is X ?

"6.1.1.6 Order of Execution"

"With the exceptions listed below, clauses are executed in the loop
body in the order in which they appear in the source. Execution is
repeated until a clause terminates the loop or until a return, go, or
throw form is encountered which transfers control to a point outside of
the loop. The following actions are exceptions to the linear 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."

So X is initialized to NIL before entering entering the first
iteration. [vide "6.1.2.2 Local Variable Initializations"]


When does the loop terminate?

"6.1.2.1 Iteration Control"

"The for and as clauses iterate by using one or more local loop
variables that are initialized to some value and that can be modified
or stepped[1] after each iteration. For these clauses, iteration
terminates when a local variable reaches some supplied value or when
some other loop clause terminates iteration."

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.

Before the first iteration is entered, but after the variables have been
initiallzed, when we determine that this list is empty.

SO the loop is never entered. And returns NIL as a consequence.

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.

--
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))
(ret))
((null xtemp) (reverse ret))
(push y ret))
all you can hope is for (1 1 1)

.



Relevant Pages

  • Yow! LOOP macros are LOOPY!
    ... By relying entirely on procedure calls to express iteration, ... to but cleaner than C's FOR loop. ... other macros going around at the time other than MacLisp's ... (bind (vi (vector-ref v i))) ...
    (comp.lang.scheme)
  • Re: Polling, Interrupts, DMA, Synchronous, Asynchronous I/O Definitions
    ... the terminology is less useful than it might be. ... though a "message loop" could arguably be claimed to be ... considering in a particular iteration but what is true for _ALL_ ... watching the "polling" version eating up every single CPU cycle ...
    (alt.lang.asm)
  • Re: Histogram of character frequencies
    ... generated object code may simply be a loop in which elements are ... believe any C compiler anywhere would reject it. ... On the first iteration of the loop you test the end of file indicator ...
    (comp.lang.c)
  • Re: Random number help
    ... is used to generate cooccurance matrix for each iteration of for loop. ... disp('the sample co-occurance matrix is as follows');% GIVING SAME ...
    (comp.soft-sys.matlab)
  • 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)