From: Raymond Toy
Subject: INITIALLY clauses in loop
Date: 
Message-ID: <sxdy8h3c8aq.fsf@rtp.ericsson.se>
On the cmucl-imp mailing list, the question came up about when the
INITIALLY clause in loop is actually run.

For example, what should this do?

(defun loop-test ()
  (loop initially (format t "initially-clause ")
	for foo = (format t "for-clause ")
	return nil)
  (terpri))

(loop-test) 

Before the November shapshot of CMUCL, it printed "initially-clause
for-clause".  It now prints "for-clause initially-clause".

CLHS 6.1.7.2 says 

    The initially construct causes the supplied compound-forms to be
    evaluated in the loop prologue, which precedes all loop code
    except for initial settings supplied by constructs with, for, or
    as.

Clisp 2.33 produces the same results as the 2004-11 snapshot of
cmucl.  I think Allegro 6 produces a different result.

There was also a previous discussion in c.l.l about this in 1993, but
that predates ANSI CL:

http://www.google.com/groups?hl=en&lr=&threadm=MBH.93Jun11084701%40wisdom.wisdom.attmail.com&rnum=4&prev=/groups%3Fq%3Dloop%2Bmacro%2Binitially%26hl%3Den%26lr%3D%26selm%3DMBH.93Jun11084701%2540wisdom.wisdom.attmail.com%26rnum%3D4

Ray

From: Peter Seibel
Subject: Re: INITIALLY clauses in loop
Date: 
Message-ID: <m3u0rrostw.fsf@javamonkey.com>
Raymond Toy <···········@ericsson.com> writes:

> On the cmucl-imp mailing list, the question came up about when the
> INITIALLY clause in loop is actually run.
>
> For example, what should this do?
>
> (defun loop-test ()
>   (loop initially (format t "initially-clause ")
> 	for foo = (format t "for-clause ")
> 	return nil)
>   (terpri))
>
> (loop-test) 
>
> Before the November shapshot of CMUCL, it printed "initially-clause
> for-clause".  It now prints "for-clause initially-clause".

The new behavior seems right. From "6.1.1.6 Order of Execution":

  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.

  * The code for any initially clauses is collected into one progn in
    the order in which the clauses appear in the source. The collected
    code is executed once in the loop prologue after any implicit
    variable initializations.

That said I suppose one could try to read something into the use of
the word "implicit" to modify "variable initializations" but the first
bullet point seems pretty clear "*All* variables are initialized
first." (emphasis mine)

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Kalle Olavi Niemitalo
Subject: Re: INITIALLY clauses in loop
Date: 
Message-ID: <87ekiuhj8g.fsf@Astalo.kon.iki.fi>
Peter Seibel <·····@javamonkey.com> writes:

> The new behavior seems right. From "6.1.1.6 Order of Execution":
>
>   The following actions are exceptions to the linear order of
>   execution:

Would it be reasonable to signal a STYLE-WARNING when the exceptions occur? 
From: Peter Seibel
Subject: Re: INITIALLY clauses in loop
Date: 
Message-ID: <m3vfc6oh28.fsf@javamonkey.com>
Kalle Olavi Niemitalo <···@iki.fi> writes:

> Peter Seibel <·····@javamonkey.com> writes:
>
>> The new behavior seems right. From "6.1.1.6 Order of Execution":
>>
>>   The following actions are exceptions to the linear order of
>>   execution:
>
> Would it be reasonable to signal a STYLE-WARNING when the exceptions occur? 

Uh, I don't think so. Because they *have* to appear out of order. That
is, INITALLY clauses, if any, have to appear textually before FOR
clauses, if any, at least according to the grammar in the LOOP
dictionary entry. Then 6.1.1.6 requires--as I read it--that the
variable initializations of the FOR clauses happen before the code in
the INITALLY clauses even though the stepping code corresponding to
the FOR clauses is obviously going to run after the code from the
INITIALLY clauses.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Björn Lindberg
Subject: Re: INITIALLY clauses in loop
Date: 
Message-ID: <hcsd5ye62mn.fsf@my.nada.kth.se>
Peter Seibel <·····@javamonkey.com> writes:

> Kalle Olavi Niemitalo <···@iki.fi> writes:
> 
> > Peter Seibel <·····@javamonkey.com> writes:
> >
> >> The new behavior seems right. From "6.1.1.6 Order of Execution":
> >>
> >>   The following actions are exceptions to the linear order of
> >>   execution:
> >
> > Would it be reasonable to signal a STYLE-WARNING when the exceptions occur? 
> 
> Uh, I don't think so. Because they *have* to appear out of order. That
> is, INITALLY clauses, if any, have to appear textually before FOR
> clauses, if any, at least according to the grammar in the LOOP
> dictionary entry. Then 6.1.1.6 requires--as I read it--that the
> variable initializations of the FOR clauses happen before the code in
> the INITALLY clauses even though the stepping code corresponding to
> the FOR clauses is obviously going to run after the code from the
> INITIALLY clauses.

One could argue that this is the more useful behaviour, since if one
needs code to run even before the variable initializations one can
always put it outside of the loop body. But the only way to have code
run between the initializations and the stepping code is if the order
is as suggested. At the moment I cannot come up with an example of
where this would be necessary or even useful though.


Bj�rn
From: Yuji Minejima
Subject: Re: INITIALLY clauses in loop
Date: 
Message-ID: <pan.2004.11.16.00.11.16.53199@nifty.ne.jp>
On Mon, 15 Nov 2004 22:58:39 +0000, Peter Seibel wrote:

> Uh, I don't think so. Because they *have* to appear out of order. That
> is, INITALLY clauses, if any, have to appear textually before FOR
> clauses, if any, at least according to the grammar in the LOOP
> dictionary entry. 

According to the following grammar rules taken from CLHS, initial
clauses can appear after for-as-clauses.

loop [name-clause] {variable-clause}* {main-clause}* => result*
name-clause::= named name 
variable-clause::= with-clause | initial-final | for-as-clause 
                                 ^^^^^^^^^^^^^
main-clause::= unconditional | accumulation | conditional | 
               termination-test | initial-final
                                  ^^^^^^^^^^^^^
I generally avoid initially clauses, but if I use them, my favorite style
is to place initially clauses after for-as-clauses. 

I think out of orderness is a very vicious trap for code readers.

Yuji.
From: Peter Seibel
Subject: Re: INITIALLY clauses in loop
Date: 
Message-ID: <m3is86o98r.fsf@javamonkey.com>
Yuji Minejima <········@nifty.ne.jp> writes:

> On Mon, 15 Nov 2004 22:58:39 +0000, Peter Seibel wrote:
>
>> Uh, I don't think so. Because they *have* to appear out of order. That
>> is, INITALLY clauses, if any, have to appear textually before FOR
>> clauses, if any, at least according to the grammar in the LOOP
>> dictionary entry. 
>
> According to the following grammar rules taken from CLHS, initial
> clauses can appear after for-as-clauses.
>
> loop [name-clause] {variable-clause}* {main-clause}* => result*
> name-clause::= named name 
> variable-clause::= with-clause | initial-final | for-as-clause 
>                                  ^^^^^^^^^^^^^
> main-clause::= unconditional | accumulation | conditional | 
>                termination-test | initial-final
>                                   ^^^^^^^^^^^^^
> I generally avoid initially clauses, but if I use them, my favorite style
> is to place initially clauses after for-as-clauses. 
>
> I think out of orderness is a very vicious trap for code readers.

Ah, good point. I didn't read far enough down. So I'd say if one were
going to emit style warnings it would be for INITALLY clauses occuring
after FOR clauses because with the exception of the variable
initialization happening first, all the INITIALLY code runs before the
FOR clauses' code.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Yuji Minejima
Subject: Re: INITIALLY clauses in loop
Date: 
Message-ID: <pan.2004.11.16.07.34.45.719655@nifty.ne.jp>
On Tue, 16 Nov 2004 01:47:32 +0000, Peter Seibel wrote:

> Ah, good point. I didn't read far enough down. So I'd say if one were
> going to emit style warnings it would be for INITALLY clauses occuring
> after FOR clauses because with the exception of the variable
> initialization happening first, all the INITIALLY code runs before the
> FOR clauses' code.

I guess all the forms in for-as-clauses except a form introduced by
the `then' preposition in for-as-equals-then clause (or a form introduced
by the `=' if `then' is omitted) are executed before all the
initially-clauses in the loop prologue. 

The code relating to for-as-clauses which gets run after
initially-clauses is end testing and stepping code which is
implicitly generated and not visible in the original loop form.

Considering initially clauses are evaluated within an environment
which includes variable bindings for for-as-clauses,  I think it's natural
to place any initially clause after all the for-as-clauses.

Yuji.
From: Peter Seibel
Subject: Re: INITIALLY clauses in loop
Date: 
Message-ID: <m3actimebu.fsf@javamonkey.com>
Yuji Minejima <········@nifty.ne.jp> writes:

> Considering initially clauses are evaluated within an environment
> which includes variable bindings for for-as-clauses, I think it's
> natural to place any initially clause after all the for-as-clauses.

Okay, I buy that.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp