(loop for ? in ? finally ?)

9 views
Skip to first unread message

Sam Steingold

unread,
Feb 23, 2000, 3:00:00 AM2/23/00
to
Does ANSI CL require that "in" variables exist in the `finally' clause?
e.g.,

(loop for x in '(1 2) finally (print x))

this prints 2 in cmucl and acl and it doesn't work in clisp.

cltl2 has an example of

(loop for i from 1 to 10
when (> i 5)
collect i
finally (print i))

which should print 11 and return the list '(6 7 8 9 10).

(and it works in acl, cmucl and clisp), but does this imply that `in'
should be allowed in `finally' too?

thanks.

--
Sam Steingold (http://www.podval.org/~sds)
Micros**t is not the answer. Micros**t is a question, and the answer is Linux,
(http://www.linux.org) the choice of the GNU (http://www.gnu.org) generation.
Only a fool has no doubts.

Barry Margolin

unread,
Feb 23, 2000, 3:00:00 AM2/23/00
to
In article <u900b9...@ksp.com>, Sam Steingold <s...@gnu.org> wrote:
>Does ANSI CL require that "in" variables exist in the `finally' clause?
>e.g.,
>
>(loop for x in '(1 2) finally (print x))
>
>this prints 2 in cmucl and acl and it doesn't work in clisp.
>
>cltl2 has an example of
>
>(loop for i from 1 to 10
> when (> i 5)
> collect i
> finally (print i))
>
>which should print 11 and return the list '(6 7 8 9 10).
>
>(and it works in acl, cmucl and clisp), but does this imply that `in'
>should be allowed in `finally' too?

I can't find anything in the LOOP description that says what value
iteration variables have after their iteration has completed. To me, that
implies that you can't count on any specific behavior, despite that
example.

Notice that in the case of a FROM-TO loop, the iteration variable ends with
the value that results from the update that takes it out of the range.
What would be the corresponding value in an IN loop? The stepping is
really taking place on a hidden variable that contains successive tails of
the list; after that is stepped, the iteration variable is assigned the CAR
of that tail. When it reaches the end of the list, this makes no sense.

--
Barry Margolin, bar...@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

Fernando D. Mato Mira

unread,
Feb 24, 2000, 3:00:00 AM2/24/00
to
Barry Margolin wrote:

> What would be the corresponding value in an IN loop? The stepping is
> really taking place on a hidden variable that contains successive tails of
> the list; after that is stepped, the iteration variable is assigned the CAR
> of that tail. When it reaches the end of the list, this makes no sense.

(CAR NIL) = NIL . CL rules.

Also, ANSI says:

6.1.2.1 Iteration Controll

"A variable binding has lexical scope unless it is proclaimed special; thus, by
default, the variable can be accessed only by forms that lie textually within the
loop."

FINALLY is textually inside the loop. As no further restrictions are made
(including "it is unspecified"-like clauses),
a program using such variables is valid. One would like to think that the spec is
being implicitly commonsensical,
so that they still hold the value they had at the end of the last iteration [maybe
because there're trigger-happy physics sheriffs around ;)]

--
Fernando D. Mato Mira
Real-Time SW Eng & Networking
Advanced Systems Engineering Division
CSEM
Jaquet-Droz 1 email: matomira AT acm DOT org
CH-2007 Neuchatel tel: +41 (32) 720-5157
Switzerland FAX: +41 (32) 720-5720

www.csem.ch www.vrai.com ligwww.epfl.ch/matomira.html


Barry Margolin

unread,
Feb 24, 2000, 3:00:00 AM2/24/00
to
In article <38B55CF2...@iname.com>,

Fernando D. Mato Mira <mato...@iname.com> wrote:
>Barry Margolin wrote:
>
>> What would be the corresponding value in an IN loop? The stepping is
>> really taking place on a hidden variable that contains successive tails of
>> the list; after that is stepped, the iteration variable is assigned the CAR
>> of that tail. When it reaches the end of the list, this makes no sense.
>
>(CAR NIL) = NIL . CL rules.

But I wouldn't expect it to call CAR at all when it has run out of cdrs.
My common sense suggests that if the iteration variable still has a value
in the FINALLY clause it would be the last element of the list. But what
if you iterate over an empty list?

LOOP is an area where X3J13 was not able to get as precise as we wanted,
because we simply ran out of time. We felt it was important to get it into
the standard, even with a number of ambiguities regarding the interaction
of some of the features. That's why I recommend that you use LOOP for
things that it's clear about, and avoid it in cases where you're not sure.

In other words, if you have to ask, you should probably not use LOOP. And
if you ask and get conflicting answers, you should expect that the
implementors will have been similarly confused, so you shouldn't expect
code to be portable among them. There are plenty of other iteration
constructs that are specified much better, so use them.

Fernando D. Mato Mira

unread,
Feb 25, 2000, 3:00:00 AM2/25/00
to
Barry Margolin wrote:

> In article <38B55CF2...@iname.com>,
> Fernando D. Mato Mira <mato...@iname.com> wrote:
> >Barry Margolin wrote:
> >
> >> What would be the corresponding value in an IN loop? The stepping is
> >> really taking place on a hidden variable that contains successive tails of
> >> the list; after that is stepped, the iteration variable is assigned the CAR
> >> of that tail. When it reaches the end of the list, this makes no sense.
> >
> >(CAR NIL) = NIL . CL rules.
>
> But I wouldn't expect it to call CAR at all when it has run out of cdrs.
> My common sense suggests that if the iteration variable still has a value
> in the FINALLY clause it would be the last element of the list. But what
> if you iterate over an empty list?

I'm not afraid about empty lists. I'm afraid about improper ones.

> In other words, if you have to ask, you should probably not use LOOP. And

Did he _have_ to ask? If it doesn't say "it's undefined" it means it's defined.
It's legal to reference the variable, so one should be able to infer exactly one
value.
The only way to keep the spec consistent w/o adding anything is by concluding
that the implementation is not allowed to store a different value in that variable
between
the end of the last iteration and the execution of the final clauses.

> if you ask and get conflicting answers, you should expect that the
> implementors will have been similarly confused, so you shouldn't expect
> code to be portable among them. There are plenty of other iteration
> constructs that are specified much better, so use them.

I can't use SERIES in the SERIES implementation (modulo bootstrapping). I don't
like
LOOP, but I like DO even less. And to do some things efficiently with DO, you have
to rplac
yourself, and even LOOP looks neat!

Now, nobody say TAGBODY or 'tail recursion', OK? ;)

Fernando D. Mato Mira

unread,
Feb 25, 2000, 3:00:00 AM2/25/00
to
"Fernando D. Mato Mira" wrote:

> Barry Margolin wrote:
>
> > In other words, if you have to ask, you should probably not use LOOP. And
>
> Did he _have_ to ask? If it doesn't say "it's undefined" it means it's defined.
> It's legal to reference the variable, so one should be able to infer exactly one
> value.
> The only way to keep the spec consistent w/o adding anything is by concluding
> that the implementation is not allowed to store a different value in that variable
> between
> the end of the last iteration and the execution of the final clauses.

Of course, you can keep it consistent by deducing that the spec is incomplete by
missing an "it's undefined" clause. Now that's something _I_ don't understand
how it would make sense, when you have an interpretation that is actually useful
and requires no retouching.

Maybe the easiest (and fastest!) thing to agree on would be just:
"When in doubt, assume the spec is consistent and complete"

Pierre R. Mai

unread,
Feb 25, 2000, 3:00:00 AM2/25/00
to
"Fernando D. Mato Mira" <mato...@iname.com> writes:

> > In other words, if you have to ask, you should probably not use
> > LOOP. And
>
> Did he _have_ to ask? If it doesn't say "it's undefined" it means it's
> defined.

That is not how standards work: If it isn't explicitly defined, then
it's undefined. Not the other way round.

Regs, Pierre.

--
Pierre Mai <pm...@acm.org> PGP and GPG keys at your nearest Keyserver
"One smaller motivation which, in part, stems from altruism is Microsoft-
bashing." [Microsoft memo, see http://www.opensource.org/halloween1.html]

Fernando D. Mato Mira

unread,
Feb 25, 2000, 3:00:00 AM2/25/00
to
"Pierre R. Mai" wrote:

> "Fernando D. Mato Mira" <mato...@iname.com> writes:
>
> > > In other words, if you have to ask, you should probably not use
> > > LOOP. And
> >
> > Did he _have_ to ask? If it doesn't say "it's undefined" it means it's
> > defined.
>
> That is not how standards work: If it isn't explicitly defined, then
> it's undefined. Not the other way round.

Then why not just erasing every sentence saying "is undefined" or "is
unspecified"?

Erik Naggum

unread,
Feb 25, 2000, 3:00:00 AM2/25/00
to
* "Fernando D. Mato Mira" <mato...@iname.com>

| Then why not just erasing every sentence saying "is undefined" or "is
| unspecified"?

primarily because we're human readers in dire need of redundancy.

secondarily because sometimes a requirement may seem to or actually imply
a too broad claim and may therefore need to be abridged or partially
retracted.

#:Erik

Fernando D. Mato Mira

unread,
Feb 25, 2000, 3:00:00 AM2/25/00
to
Erik Naggum wrote:

I've never seen redundancy as the primary reason, either in CL or Scheme, but
to:

1. Give leeway to implementors.
2. Avoid giving semantics to a nonsensical expression.
3. Leave an issue open for experimentation/analysis.

Barry Margolin

unread,
Feb 25, 2000, 3:00:00 AM2/25/00
to
In article <38B66866...@iname.com>,

Fernando D. Mato Mira <mato...@iname.com> wrote:
>Did he _have_ to ask? If it doesn't say "it's undefined" it means it's defined.

But if it doesn't define it, it's not defined, hence undefined.

>It's legal to reference the variable, so one should be able to infer exactly one
>value.

>The only way to keep the spec consistent w/o adding anything is by concluding
>that the implementation is not allowed to store a different value in that
>variable
>between
>the end of the last iteration and the execution of the final clauses.

Why? The expansion of a FOR-IN-BY loop could look like:

(setq ,iteration-var 'dummy-value)
(setq ,internal-var (funcall ,by ,internal-var))
(when (endp ,internal-var)
(go epilogue))
(setq ,iteration-var (car ,internal-var))

So, during the epilogue, the iteration variable would contain that dummy value.

I don't know *why* someone would do that, but I don't think it's
disallowed. It can only be detected in the FINALLY clause, and the spec
never says what the iteration variable should have during that clause.

Xah

unread,
Feb 25, 2000, 3:00:00 AM2/25/00
to
"Fernando D. Mato Mira" <mato...@iname.com> wrote
> | Then why not just erasing every sentence saying "is undefined" or "is
> | unspecified"? [of a Standard specification]

doctor Naggum <er...@naggum.no> wrote:
> primarily because we're human readers in dire need of redundancy.

Your crime here is the almost random shooting off of sparkles.

Actually, it is not YOUR crime but i have detected such a criminal tendency
in this direction of thought in your writings. In any case, i'll be shedding
the blood of a monkey to illuminate pigs in the common.

The human character does not stem from a set of mathematical axioms. One
cannot define what are our "dire needs" of essence. Our "needs" shapes with
understanding and progress. Few centuries ago we humans have the dire need
to believe in deity or other nonsense. Much longer ago our nature includes
the need to kill and sacrifice. But not today. (at least i hope not.)

Today we may have the dire need and comfort for redundancy, but humans of
the future _may_ be highly economic in functioning yet possibly grow in
elaborateness in emotions but such a "dire need for redundancy" in not
necessarily for keepers.

Incorrect specification of human nature in an unfaltering stance is a
passive obstacle towards progress.

I hope you and Kent Pitman stop pouting such nonsense in defense of the
nature of ad hoc Common Lisp.

> secondarily because sometimes a requirement may seem to or actually imply
> a too broad claim and may therefore need to be abridged or partially
> retracted.
>

> #:Erik

Xah
x...@xahlee.org
http://xahlee.org/PageTwo_dir/more.html


Erik Naggum

unread,
Feb 25, 2000, 3:00:00 AM2/25/00
to
* "Fernando D. Mato Mira" <mato...@iname.com>
| I've never seen redundancy as the primary reason ...

I was referring to an inherent characteristic of human languages, and as
such, redundancy is indeed a primary. indeed, some redundancy is a
_good_ thing in human communication. that is, what might be considered
"redundant" from a purist point of view is actually necessary to maintain
proper communication conduits between people who can't pay 100% attention
100% of the time and who most certainly can't cope with 100% of the
ramification of every statement 100% of the time. so we yield to the
nature of the human mind instead of removing all forms of redundancy.

#:Erik

Xah

unread,
Feb 26, 2000, 3:00:00 AM2/26/00
to
Erik Naggum <er...@naggum.no> wrote:
> I was referring to an inherent characteristic of human languages, and as
> such, redundancy is indeed a primary. indeed, some redundancy is a
> _good_ thing in human communication. that is, what might be considered
> "redundant" from a purist point of view is actually necessary to maintain
> proper communication conduits between people who can't pay 100% attention
> 100% of the time and who most certainly can't cope with 100% of the
> ramification of every statement 100% of the time. so we yield to the
> nature of the human mind instead of removing all forms of redundancy.
>
> #:Erik

Dear Fernando,

You have been _used_ as a vehicle for communication by Erik. You know how
sometimes you love someone but are wordless at confrontation? You say to
your buddy "Can you ask Mary to see me after class? Tell her i really like
her". I hope you don't become a messenger and becoming to be slapped from
both sides.

As far as what Naggum said, i do appreciate his clarification of his
inadequacy at lettering. _It does make perfect sense_. However, you should
go back to tell him that he lacks vision. Human weaknesses need to be
removed, not cuddled. I don't mean that we should all just take a knife and
cut our hearts out and replace it with a pacemaker. But, with the help of
knowledge we could improve our hearts in efficiency, not redundancy. If we
are smug about current state of affairs then we'll only have _legacy_, such
as Common Lisp. And if we loathe new technology such as Haskell then
legacies become warts.

I hesitate to call doctor Naggum a wart, but probably something like that.

Btw, Fernando: although i don't know you but thank you for being a vehicle
of communication. Love is nothing but a game. Please understand and forgive
him for this. If he loves me, he needs to tell me directly.

Xah
x...@xahlee.org
http://xahlee.org/PageTwo_dir/more.html


Barry Margolin

unread,
Feb 28, 2000, 3:00:00 AM2/28/00
to
In article <38B9621D...@iname.com>,
Fernando D. Mato Mira <mato...@iname.com> wrote:
>Before going on, please note that Sam asked this question
>as an IMPLEMENTOR, not a user.
>
>Everybody here is saying "When in doubt, be conservative". It
>just happens that a writer of protable programs must assume something is
>`undefined
>or unspecifed'
>if he can't figure out the meaning, while an implementor must assume it's well
>specified, and that he can't go happily making things illegal.

But if he can't find a place in the spec where it says what he must do, he
can do whatever he wants.

>Barry Margolin wrote:
>
>> In article <38B66866...@iname.com>,
>> Fernando D. Mato Mira <mato...@iname.com> wrote:
>> >Did he _have_ to ask? If it doesn't say "it's undefined" it means it's
>defined.
>>
>> But if it doesn't define it, it's not defined, hence undefined.
>

>It's has not been explicitly forbidden to ask for values of variables of certain
>values that are in scope.
>The results might be underspecified, but action is in no way undefined,
>which means
>the implementor
>should not return whatever he pleases, but one of the results that would
>follow from
>trivial interpretation.

I don't recall any place in the spec where it says that you can assume the
obvious implementation of something.

>
>> >It's legal to reference the variable, so one should be able to infer
>exactly one
>> >value.
>>
>> >The only way to keep the spec consistent w/o adding anything is by concluding
>> >that the implementation is not allowed to store a different value in that
>> >variable
>> >between
>> >the end of the last iteration and the execution of the final clauses.
>>
>> Why? The expansion of a FOR-IN-BY loop could look like:
>>
>> (setq ,iteration-var 'dummy-value)
>> (setq ,internal-var (funcall ,by ,internal-var))
>> (when (endp ,internal-var)
>> (go epilogue))
>> (setq ,iteration-var (car ,internal-var))
>

>The spec says "The variable var is bound to the successive elements of
>the list in
>form1
>before each iteration".

By the time an iteration occurs, the second SETQ will have taken place,
thus meeting that requirement.

Fernando D. Mato Mira

unread,
Feb 29, 2000, 3:00:00 AM2/29/00
to
Barry Margolin wrote:

> In article <38B9621D...@iname.com>,
> Fernando D. Mato Mira <mato...@iname.com> wrote:
> >Before going on, please note that Sam asked this question
> >as an IMPLEMENTOR, not a user.
> >
> >Everybody here is saying "When in doubt, be conservative". It
> >just happens that a writer of protable programs must assume something is
> >`undefined
> >or unspecifed'
> >if he can't figure out the meaning, while an implementor must assume it's well
> >specified, and that he can't go happily making things illegal.
>
> But if he can't find a place in the spec where it says what he must do, he
> can do whatever he wants.

Besides the fact that such an approach shows the true value of an spec w/o a formal
definition,
or at least verbosely written in natural language to accomplish the same effect that
would mean:

1. Implementors are free not to play by the same rules as everybody else.
2. It is more important for an implementor to be conservative than for a user. He's
not sure of
the true intention of the persons writing the ambiguous spec, which, from a user's
point of view might
seem obvious, especially if one is `blinded' by common sense. If the user makes a
`mistake' and writes 1M
lines of code under that assumption (specially when it's also common to assume that
whatever the implementation gives
must be right, an illusion compounded by the fact that if it's the common sense
answer, it really looks OK), he is the
only one to suffer when porting. If the implementor decides to do as he pleases, he
can cause a lot of no longer maintained
programs to break. [Fortunately, people like Franz's are very good at applying
common sense].

> I don't recall any place in the spec where it says that you can assume the
> obvious implementation of something.

That's the BIGGEST MISTAKE in the spec. It should clearly state at the beginning
that it operates under a closed world assumption. Explicitly marking things as
undefined
or unspecifed makes things worse. Suddenly, the whole thing is almost completely
ambiguous.

> >The spec says "The variable var is bound to the successive elements of
> >the list in
> >form1
> >before each iteration".
>
> By the time an iteration occurs, the second SETQ will have taken place,
> thus meeting that requirement.

Duh. Why did you delete the rest of the message?

Just on Friday somebody came to me with some specs. I told him to make two
versions: one with lots of redundant safety stuff removed to give to the users
so that they don't assume they can send anything but the canonical command sequences

(telescope mirrors and sensors are expensive); the other version is the
implementors' spec,
so that even if the users send `undefined' sequences, we won't break anything (and
many will
just work `as if'. Although raising an error couild be seen as better to safeguard
against controller software paranoia violations,
if the bug is not to raise the error, you lose anyway. The best is to BOTH apply the
safety commands and emit the error.

Translated into the world of CL, the best is to both do the common sense thing and
emit a warning (not an error,
so that old common sense programs still work).

You know better than almost anybody else in this group, that precedent is a big
factor in X3J13 decisions. If someone
is already implementing the expected behavior, there's a good chance it'll get set
in stone in the next round. You only
lose by doing something else. Unless you have a _more_ useful idea of what to
return!

Example: FOR..ON is more ambiguous because it says the vars are bound to succesive
tails. However,
you know that during the last iteration, the var associated with the list
terminating the loop is bound to the last cons.
Binding to NIL at exit in the case of a proper list is useless, and it's much better
if the var still references the last cons,
besides being consistent with the straightforward FOR..IN interpretation.

IMPORTANT NOTE:
The description of arithmetic FOR was kind of messy in CLtL2, and it seems to have
been cleanep up to be consistent
with the example mentioned (although that is misteriously absent from the spec).
CLtL2 seemed to leave the door
open to consider the example wrong (where it should print 10 instead of 11). This
behavior, while strange from a
traditional C et al. mindset, would be more Lispy ["Eurisky"?] in the presence of
the other two, while playing nicely with examples
like:

(loop for x fixnum from 0 upto most-positive-fixnum
<do fixnum stuff>
finally <do more fixnum stuff>)

Erik Naggum

unread,
Feb 29, 2000, 3:00:00 AM2/29/00
to
* Bary Margolin

| But if he can't find a place in the spec where it says what he must do,
| he can do whatever he wants.

* Fernando D. Mato Mira


| Besides the fact that such an approach shows the true value of an spec w/o
| a formal definition, or at least verbosely written in natural language to
| accomplish the same effect that would mean:

standards are legal documents. they follow the same principle as every
other legal document: that which it does not say is not covered. laws
are defined similarly: if it isn't forbidden, you can do it. (but in the
case of government agencies: if it isn't prescribed, you can't do it.)

| 1. Implementors are free not to play by the same rules as everybody else.

so what would you need to stop them from doing this in your ideal world?
(I assume permissions and grants from gilds or government agencies.)

in this world, users and customers make informed choices and the market
has the role of the control mechanism. not to be snotty or anything, but
it tends to come as a surprise to Europeans that the market can work
without serious government intervention and licenses to produce goods.
which is why the new EU standard for condoms specifies one size for the
entire continent, ignoring well-known physiological differences between
regions, and why we have an EU standard for the "curvature" of bananas.

#:Erik

Fernando D. Mato Mira

unread,
Mar 1, 2000, 3:00:00 AM3/1/00
to
Erik Naggum wrote:

>
> | 1. Implementors are free not to play by the same rules as everybody else.
>
> so what would you need to stop them from doing this in your ideal world?
> (I assume permissions and grants from gilds or government agencies.)

The closed-world clause. Probably better if it applies to implementors only, so
that
users may still not fully rely on derivations following from non-audited axioms
(for example
a LOOP spec rushed out), so that a practice does not get set in stone
prematurely
(eg, "11 instead of 10").

Chris Riesbeck

unread,
Mar 1, 2000, 3:00:00 AM3/1/00
to
In article <38BBA5B5...@iname.com>, "Fernando D. Mato Mira"
<mato...@iname.com> wrote:

>Barry Margolin wrote:
>
>> I don't recall any place in the spec where it says that you can assume
>> the
>> obvious implementation of something.
>
>That's the BIGGEST MISTAKE in the spec. It should clearly state at the
>beginning
>that it operates under a closed world assumption. Explicitly marking
>things as undefined
>or unspecifed makes things worse. Suddenly, the whole thing is almost
>completely ambiguous.

In some cases, replacing "undefined" with a particular
choice would invalidate an existing CL implementation.

This is a burden not only on the vendor but on its users,
because the next upgrade to their CL will break their code.

Yes, it wasn't portable, but they were never expecting
to move to another platform, and still they pay the price.

This is particularly hard on users of less popular
machine/OS configurations supported at best by 1 CL option.

So I disagree that in general this is a BIG MISTAKE.

Reply all
Reply to author
Forward
0 new messages