Lisp HUG Maillist Archive

(loop when ... end)

Unable to parse email body. Email id is 2806

RE: (loop when ... end)

> From: owner-lisp-hug@xanalys.com 
> [mailto:owner-lisp-hug@xanalys.com] On Behalf Of Nick Levine
> Sent: 23 September 2004 12:34
> To: lisp-hug@xanalys.com
> Subject: (loop when ... end)
> 
> Section 6.1.6 of CLHS states:
> 
> The optional loop keyword "end" marks the end of the clause. If this
> keyword is not supplied, the next loop keyword marks the end. The
> construct "end" can be used to distinguish the scoping of compound
> clauses.
> 
> So I would expect
> 
>    (loop for x below 10 when (< x 3) collect x collect x end)
> 
> to work rather than - as in LWW 4.3.7 and for that matter ACL 6.2 - 
> telling me that end is an unknown loop keyword.
> 
> Have I read the spec wrong? Is this a defect in the
implementation(s)?
> Or what?
> 
> - nick

The second COLLECT has already ended the WHEN, and an END has
to match an IF, WHEN or UNLESS.

Try this:

(loop for x below 10 when (< x 3) collect x end collect x)
=> (0 0 1 1 2 2 3 4 5 6 7 8 9)

I guess the error message is a little confusing though.

(And thanks for introducing me to END.)



RE: (loop when ... end)

> From: owner-lisp-hug@xanalys.com 
> [mailto:owner-lisp-hug@xanalys.com] On Behalf Of Simon Katz
> Sent: 23 September 2004 13:42
> To: lisp-hug@xanalys.com
> Subject: RE: (loop when ... end)
> 
> > From: owner-lisp-hug@xanalys.com 
> > [mailto:owner-lisp-hug@xanalys.com] On Behalf Of Nick Levine
> > Sent: 23 September 2004 12:34
> > To: lisp-hug@xanalys.com
> > Subject: (loop when ... end)
> > 
> > Section 6.1.6 of CLHS states:
> > 
> > The optional loop keyword "end" marks the end of the clause. If
this
> > keyword is not supplied, the next loop keyword marks the end. The
> > construct "end" can be used to distinguish the scoping of compound
> > clauses.
> > 
> > So I would expect
> > 
> >    (loop for x below 10 when (< x 3) collect x collect x end)
> > 
> > to work rather than - as in LWW 4.3.7 and for that matter ACL 6.2
- 
> > telling me that end is an unknown loop keyword.
> > 
> > Have I read the spec wrong? Is this a defect in the
> implementation(s)?
> > Or what?
> > 
> > - nick
> 
> The second COLLECT has already ended the WHEN, and an END has
> to match an IF, WHEN or UNLESS.
> 
> Try this:
> 
> (loop for x below 10 when (< x 3) collect x end collect x)
> => (0 0 1 1 2 2 3 4 5 6 7 8 9)
> 
> I guess the error message is a little confusing though.
> 
> (And thanks for introducing me to END.)

On second thoughts...

The spec says "If this keyword [END] is not supplied, the next
loop keyword marks the end." So I guess the /first/ COLLECT marks
the end of the WHEN (but it is included within the scope of the
WHEN).

??



Re: (loop when ... end)

Unable to parse email body. Email id is 2809

RE: (loop when ... end)

>    Try this:
> 
>    (loop for x below 10 when (< x 3) collect x end collect x)
>    => (0 0 1 1 2 2 3 4 5 6 7 8 9)
> 
> Interesting. But not what I wanted - my fault for not defining what
I
> meant by "to work".
> 
> I was hoping it would return (0 0 1 1 2 2).
>

Do you know about AND?

(loop for x below 10 when (< x 3) collect x and collect x)
=> (0 0 1 1 2 2)




Re: (loop when ... end)

On Thu, Sep 23, 2004, 09:00, Nick Levine <ndl@ravenbrook.com> wrote
>   > So I would expect
>   > 
>   >    (loop for x below 10 when (< x 3) collect x collect x end)
>   > 
>   > to work rather than - as in LWW 4.3.7 and for that matter ACL 6.2
>   > - telling me that end is an unknown loop keyword.
>
>   ...
>
>   The second COLLECT has already ended the WHEN, and an END has
>   to match an IF, WHEN or UNLESS.
>
>   Try this:
>
>   (loop for x below 10 when (< x 3) collect x end collect x)
>   => (0 0 1 1 2 2 3 4 5 6 7 8 9)
>
>Interesting. But not what I wanted - my fault for not defining what I
>meant by "to work".
>
>I was hoping it would return (0 0 1 1 2 2).

In my experience, whenever using any combination of loop clauses that I've 
not used at least 20 times before, it's best to macroexpand the LOOP 
expression to see what it produces.



Re: (loop when ... end)

On Thu, 23 Sep 2004 13:42:12 +0100, "Simon Katz" <sk@nomistech.com> wrote:

> The second COLLECT has already ended the WHEN

If that is the case one wonders what END is good for anyway...


RE: (loop when ... end)

Edi Weitz:
> > The second COLLECT has already ended the WHEN
> 
> If that is the case one wonders what END is good
> for anyway...

Hmmm, yes. I think it ties in with using AND.

Here's an example where END makes a difference:


(loop for x from 1 below 10
      when (< x 7)
      when (evenp x) collect x
      end
      and collect (* x 100))
=> (100 2 200 300 4 400 500 6 600)


(loop for x from 1 below 10
      when (< x 7)
      when (evenp x) collect x
      and collect (* x 100))
=> (2 200 4 400 6 600)


So I think:
- WHEN has a subsidiary clause (introduced by the
  first COLLECT in Nick's original example).
- When the spec says "If this keyword [END] is not
  supplied, the next loop keyword marks the end",
  this means the next loop keyword after the
  subsidiary clause.



Re: (loop when ... end)

Simon Katz wrote:

> So I think:
> - WHEN has a subsidiary clause (introduced by the
> first COLLECT in Nick's original example).
> - When the spec says "If this keyword [END] is not
> supplied, the next loop keyword marks the end",
> this means the next loop keyword after the
> subsidiary clause.

Maybe you're right. Then again, maybe you're not.

LOOP is nice, but the corner cases are a mess. IMHO the best
solution is to just use Jonathan Amsterdam's ITERATE when things
get complicated.

Marc Battyani's CL-PDF (or was it CL-TYPESETTING?) also recently
got bitten by different interpretations of some LOOP subtleties.
He decided to switch to ITERATE. Problem solved.

Arthur


RE: (loop when ... end)

Arthur Lemmens:
> Sent: 23 September 2004 15:04
> To: lisp-hug@xanalys.com
> Subject: Re: (loop when ... end)
> 
> Simon Katz wrote:
> 
> > So I think:
> > - WHEN has a subsidiary clause (introduced by the
> > first COLLECT in Nick's original example).
> > - When the spec says "If this keyword [END] is not
> > supplied, the next loop keyword marks the end",
> > this means the next loop keyword after the
> > subsidiary clause.
> 
> Maybe you're right. Then again, maybe you're not.
> 
> LOOP is nice, but the corner cases are a mess.

Yes. I wouldn't use those ANDs and ENDs in real code.



Re: (loop when ... end)

Simon Katz wrote:

> Arthur Lemmens:
>> Maybe you're right. Then again, maybe you're not.
>>
>> LOOP is nice, but the corner cases are a mess.
>
> Yes. I wouldn't use those ANDs and ENDs in real code.

I use AND. I rarely, if ever, use END.

(I tried grepping for END in my code, but that was useless.
I use it far too often as a variable name.)

Arthur


Updated at: 2020-12-10 08:55 UTC