Mailing List Archive

1 2  View All
1.5.2 for: else: [ In reply to ]
> William Tanksley <wtanksle@dolphin.openprojects.net> wrote:
> > The very worst part of the current else: behavior is that it changes the
> > meaning of else. In other constructs, else is an alternate path to take
> > if the data being tested fails a single expression test. In this
> > contruct, else is a path taken if the code block belonging to the
> > previous test executes a certain instruction.
>
> nope. you've got it all backwards. consider this:
>
> for an "if" statement, "else" is a path taken if the
> expression evaluates to false.
>
> for a "while" statement, "else" is a path taken if the
> expression evaluates to false. or in other words,
> when the loop terminates by natural causes.
>
> for a "for" statement, "else" is a path taken when
> there are no more elements to loop over. or
> in other words, when the loop terminates by
> natural causes.
>
> not that complicated, was it?

I think quite a few people would expect only one of the parts to
execute, like in if..else, and not both of them. So this extension of
the meaning of 'else' may come as a surprise for those (including me,
actually).

But, the feature itself is nice, and the keyword is not going to
change, is I guess it's no use whining about it. ^_^

--Hans Nowak (zephyrfalcon@hvision.nl)
Homepage: http://fly.to/zephyrfalcon
Python Snippets: http://www.hvision.nl/~ivnowa/snippets/
The Purple Kookaburra Forum: http://www.delphi.com/kookaburra/
1.5.2 for: else: [ In reply to ]
On Thu, 29 Jul 1999 08:51:15 +1200, Greg Ewing wrote:
>Gordon McMillan wrote:

>> But finding a match in a list, and testing whether you
>> fell off the end without finding one, is (without the else clause) a
>> much messier proposal.

>Not if you go about it the right way. I always
>put such loops in a procedure of their own,
>and use return:

>Not only does this not require a weird else
>clause, it doesn't require break either. I
>almost never use break - and when I do I usually
>regret it later. I wouldn't mind if there weren't
>any break - and without break, there would be no
>need for the weird else.

I have to admit that I do the same -- this is why I've never been tripped
up by the else.

>Greg

--
-William "Billy" Tanksley
1.5.2 for: else: [ In reply to ]
On Wed, 28 Jul 1999 20:11:10 GMT, Fredrik Lundh wrote:
>William Tanksley <wtanksle@dolphin.openprojects.net> wrote:
>> > for an "if" statement, "else" is a path taken if the
>> > expression evaluates to false.

>> Close enough -- I would say it's the path taken if the 'if' block isn't
>> executed.

>you can say what you want, but it isn't defined
>that way; the language reference says:

> "If all expressions are false, the suite of
> the else clause, if present, is executed."
> (where "all expressions" are the expressions
> for all if/elif clauses in the statement)

>if you continue reading, you'll find:

> "if the expression is false (which may be
> the first time it is tested) the suite of the
> else clause, if present, is executed"

>and

> "when the items are exhausted (which is
> immediately when the sequence is empty),
> the suite in the else clause, if present, is
> executed"

>for ALL these statements, the else clause is exe-
>cuted if and only if ALL controlling expressions
>evaluate to FALSE.

But that's not even superficially true for the current behavior of a loop.
A loop's else clause is executed even when there were TRUE results of the
controlling expressions.

In fact, the loop's else clause is executed when a single FALSE is
returned from an often hidden evaluation.

>huh? the "else" clause isn't involved in the loop's
>termination at all; it's executed when the con-
>trolling expression becomes false. if you raise
>an exception, or use the break statement, or
>return to the caller, you don't end up in the
>"else" clause by a very simple reason: the con-
>trolling expression isn't false.

This actually makes a lot of sense for a while statement, since there's an
explicit single-valued controlling expression. If the while statement
were the only loop statement with an else, I wouldn't bother arguing about
it; I would just think that I would rather not use a break for that
purpose (but scripting languages are wonderful that way, you get to write
code that makes sense to YOU, not to me or Guido).

>I repeat:

>for ALL these statements, the else clause is exe-
>cuted if and only if ALL controlling expressions
>evaluate to FALSE.

Except 'for', where it executes if and only if _one_ of the "controlling
expressions" (all of which are implicit) evaluates to FALSE.

If it truly was consistent with your own definition, then it would execute
if and only if none of the controlling expressions ever evaluated to TRUE
-- in other words, if the for loop never iterated.

I think I got you by your very own words.

>you can argue as much as you want, but that's the
>way it is. you gotta live with it (unless you have your
>own time machine, of course ;-)

I agree with this, of course :).

I'm nore agitating for Python 2.0. But then I'd be happy to see else go
away or stay the same, too; it's too minor of a feature. I guess, then,
that I'm merely defending my point of view.

></F>

--
-William "Billy" Tanksley
1.5.2 for: else: [ In reply to ]
On Wed, 28 Jul 1999 16:38:24 -0500, Gordon McMillan wrote:
>William Tanksley wrote:
>> On Tue, 27 Jul 1999 21:43:00 -0500, Gordon McMillan wrote:

>[snip Billy's silly error and his entirely insufficient embarassment
><wink>]

:)

>> However, you're wrong about the best way to detect a 2 in the list
>> using this style. To steal the same example:

>> try:
>> for x in [1,2,3]:
>> print x
>> if x == 2: raise neverMind
>> print "modern else clause here"
>> except neverMind: print "found two"
>> else:
>> print "another place to put the modern else clause"

>> Of course, by demonstrating both ways to do it, I'm making the code
>> more complex; but you can see that this solution solves the problem
>> quite elegantly.

>WIth an extra class, and 3 or 4 more lines of code, not to mention
>treading on the toes of all who think exceptions should only be used
>for exceptional conditions (or maybe it _is_ exceptional when
>something you wrote works <1e3 wink>).

You don't need the extra class -- you can raise a string if somebody's
linecounting you. But who really cares? The result is pretty darn clear.
There are no common misconceptions to fight when you're writing or reading
it (I count three people who have posted to say nothing more than "gee,
that wasn't what I expected!" about the current behavior). This code just
works!

And as for exceptions -- anyone who uses break together with else-loop but
shuns exceptions is in serious need of psychological help. That's WAY
tweaked. Exceptions are a wonderful tool; break is a useful hack.

Oh, and if you REALLY like the current behavior of else-loop, you can
still have it if else-loop were gone -- like this:

try:
for x in list:
if iffers(x): raise "no!"
yadda(x)
except "no!": pass
else:
twiddle()

That's two extra lines, and one level of nesting -- for the _exact_ same
functionality, only much more likely to be comprehended.

>> The place to use MY definition of 'else', OTOH, is when you're
>> building a structure during the iteration, but the result of an
>> empty loop is different than the initial value the variable has to
>> have when going through the loop.

>> Here you go. This example might convert a Python list into a Lisp
>> tree-list -- but to imitate Lisp (okay, it's a toy problem, I'm
>> cheating) an empty list produces NIL ~= None.

>> var = Node(None,None)
>> for x in pyList:
>> var.car = x
>> var.cdr = Node()
>> else:
>> var = None

>Not a Lisper, but isn't what you're doing better done thusly:

No no no! Don't be silly -- I was giving an example of how my idea of
else should work. I don't have time to design a system which NEEDS to be
done this way.

but-I-do-have-time-to-whine-about-something-that-isn't-going-to-change-ly
yr's,

--
-William "Billy" Tanksley
1.5.2 for: else: [ In reply to ]
William Tanksley <wtanksle@dolphin.openprojects.net> wrote:
> >for ALL these statements, the else clause is exe-
> >cuted if and only if ALL controlling expressions
> >evaluate to FALSE.
>
> But that's not even superficially true for the current behavior of a loop.
> A loop's else clause is executed even when there were TRUE results of the
> controlling expressions.

huh? there's only ONE *controlling* expression in
the loop: the internal test that checks if the
sequence has any more items. the else clause
is executed if and only if THAT expression eval-
Traceback (innermost last):
File "effbot.py", line 12032, in effbot
File "effbot.py", line 3428, in generate_reply
raise ImpedanceMismatch # bailing out
effbot.ImpedanceMismatch
1.5.2 for: else: [ In reply to ]
On Fri, 30 Jul 1999, Fredrik Lundh wrote:

> huh? there's only ONE *controlling* expression in
> the loop: the internal test that checks if the
> sequence has any more items. the else clause
> is executed if and only if THAT expression eval-
> Traceback (innermost last):
> File "effbot.py", line 12032, in effbot
> File "effbot.py", line 3428, in generate_reply
> raise ImpedanceMismatch # bailing out
> effbot.ImpedanceMismatch

The truth is out. "Frederick Lundh" is a bot!
1.5.2 for: else: [ In reply to ]
Patrick> The truth is out. "Frederick Lundh" is a bot!

Now we have to deal with the fredbot as well as the timbot. Anybody for a
quick game of RoboWar?

Skip Montanaro | http://www.mojam.com/
skip@mojam.com | http://www.musi-cal.com/~skip/
847-475-3758
1.5.2 for: else: [ In reply to ]
> for an "if" statement, "else" is a path taken if the
> expression evaluates to false.

In my mind, for an "if" statement, "else" is the path taken
when the BODY is not executed at all.

> for a "while" statement, "else" is a path taken if the
> expression evaluates to false. or in other words,
> when the loop terminates by natural causes.

And therefore, the "else:" on either while or for loops, as
defined in Python, is completely counterintuitive.

> not that complicated, was it?

It's not complicated, it's just something that is easily
open to multiple interpretations, depending on how one views
the normal, common usage of the word. As such, it is one of the
very few things in Python that (for some of us) is not clear from
context -- it just doesn't look obvious what the behavior should
be. So, in the spirit of python, we don't use it. Unfortunately,
others do. I hope no one ever uses it without a comment explaining
what it means.

I know it ain't gonna change soon; but one can hope that perhaps
Python 2.0 could choose a better keyword for it -- one that doesn't
come with preconceived notions that the current definition violates.
--
Doug Landauer landauer@apple.com (work)
landauer@scruznet.com (not-work)
1.5.2 for: else: [ In reply to ]
Skip wrote:
>Now we have to deal with the fredbot as well as the timbot.
>Anybody for a quick game of RoboWar?

note: the correct name is "effbot".

see
http://www.pythonware.com/people/fredrik/status.htm
for more info.

also see:
http://www.robocup.org

and:
http://www.aftonbladet.se/nyheter/9907/30/robocup.html
(in swedish, but you should be able to find the real-
player video links anyway)

and yes, we do apologise for that exception. usually,
such messages should be caught before they end up on
the list.

Cheers,
the eff-bot administrators


_______________________________________________________________
Get Free Email and Do More On The Web. Visit http://www.msn.com
1.5.2 for: else: [ In reply to ]
In article <379FC039.73C436FC@mincom.com>,
Martin Pool <martinp@mincom.com> wrote:
> I doubt if I'll often use for: else or try: else, and perhaps
> they could have clearer names,

How about for: then?

but-what-about-all-my-variables-named-'then'-ly yrs, Cliff


--
Cliff Crawford -><-
http://www.people.cornell.edu/pages/cjc26
empty-handed I go,
)O( and behold the spade is in my hands


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
1.5.2 for: else: [ In reply to ]
[William Tanksley]
> ...
> Oh, and if you REALLY like the current behavior of else-loop, you can
> still have it if else-loop were gone -- like this:
>
> try:
> for x in list:
> if iffers(x): raise "no!"
> yadda(x)
> except "no!": pass
> else:
> twiddle()
>
> That's two extra lines, and one level of nesting -- for the _exact_ same
> functionality, only much more likely to be comprehended.

Except that when I see that loop, I'm at a loss to guess whether the
"except" clause is intended to catch otherwise-uncaught "no!" exceptions
raised by list.__getitem__, iffers(), and yadda() too. Presumably the
intent is that it should not, but there's no easy way to stop it from
catching unintended stuff too short of defining a unique exception for each
loop. for+break+else doesn't have this problem.

use-exceptions-for-exceptions-and-break-for-things-that-shouldn't-ly y'rs -
tim
1.5.2 for: else: [ In reply to ]
On Sat, 31 Jul 1999 01:15:54 -0400, Tim Peters wrote:
>[William Tanksley]

>> Oh, and if you REALLY like the current behavior of else-loop, you can
>> still have it if else-loop were gone -- like this:

>> try:
>> for x in list:
>> if iffers(x): raise "no!"
>> yadda(x)
>> except "no!": pass
>> else:
>> twiddle()

>> That's two extra lines, and one level of nesting -- for the _exact_ same
>> functionality, only much more likely to be comprehended.

>Except that when I see that loop, I'm at a loss to guess whether the
>"except" clause is intended to catch otherwise-uncaught "no!" exceptions
>raised by list.__getitem__, iffers(), and yadda() too. Presumably the
>intent is that it should not, but there's no easy way to stop it from
>catching unintended stuff too short of defining a unique exception for each
>loop. for+break+else doesn't have this problem.

Very good point, Tim.

The best solution of all is to simply not use features of the language
which I find objectionable for whatever reason. I'm just disappointed in
the odd definition of for-else. I'm glad to have learned it this way
rather than by painful debugging, and I don't think any of us are likely
to forget now :).

Memo to self -- don't use for-else, it doesn't do what it looks like it's
doing.

--
-William "Billy" Tanksley
1.5.2 for: else: [ In reply to ]
ALL:
I'm a newbie so I may be out of line here, but the for: else: construct
is pretty bad. It just does not read well, and implies the incorrect
operation; it reminds me of some of the weird FORTH stuff. Why not use
another word for this and not overload 'else'? Maybe for: also:, or
something more in line with the intended purpose. Sure there may be good
reasons for else that I (newbie) do not know, but I thought Python was
supposed to enable ease of reading, not only writing (ala Perl).

TC Mits.


Hans Nowak <ivnowa@hvision.nl> wrote in message
news:199907272208.AAA06264@axil.hvision.nl...
>
> On 27 Jul 99, Oleg Broytmann wrote:
>
> > > Loop statements may have an else clause; it is executed when the loop
> > > terminates through exhaustion of the list (with for) or when the
> > > condition becomes false (with while), but not when the loop is
> > > terminated by a break statement. [..]
> > [skip]
> > > Else clauses get executed on normal loop exit, even if the loop was
> > > 'empty'. It does not get executed when you 'break' out of a loop.
> >
> > Aha, thanks. I expected "else" to be executed when "for" not executed
> > on
> > empty list. Wrong assumption.
>
> This one has bitten me too in the past. One of the few non-intuitive
> parts of Python, methinks. :(
>
> --Hans Nowak (zephyrfalcon@hvision.nl)
> Homepage: http://fly.to/zephyrfalcon
> Python Snippets: http://www.hvision.nl/~ivnowa/snippets/
> The Purple Kookaburra Forum: http://www.delphi.com/kookaburra/
1.5.2 for: else: [ In reply to ]
T. C. Mits wrote:
>
> ALL:
> I'm a newbie so I may be out of line here, but the for: else: construct
> is pretty bad. It just does not read well, and implies the incorrect
> operation;

I would agree that this use of 'else' is counterintuitive, though is
isn't quite as bad as Perl's use of 'continue'. Java's keyword,
'finally', would be another option, but that carries the meaning of a
block that is always executed.

In practice, it doesn't seem to be necessary, so it can be ignored by
old C coders who can't quite remember how it works.

--
Bear Technology Making Montana safe for Grizzlies

http://people.montana.com/~bowman/
1.5.2 for: else: [ In reply to ]
On Thu, 29 Jul 1999 08:51:15 +1200, Greg Ewing <greg.ewing@compaq.com> wrote:

>Gordon McMillan wrote:
>>
>> But finding a match in a list, and testing whether you
>> fell off the end without finding one, is (without the else clause) a
>> much messier proposal.
>
>Not if you go about it the right way. I always
>put such loops in a procedure of their own,
>and use return:
>
> def find_the_holy_grail(stuff):
> for x in stuff:
> if is_holy_grail(x):
> return x
> return None

Unfortunately, python lacks lexical scoping, which means this technique
cannot be easily generalised. In particular, if the loop body requires
access to the current context, you can't use a function to encapsulate it.


John Max Skaller ph:61-2-96600850
mailto:skaller@maxtal.com.au 10/1 Toxteth Rd
http://www.maxtal.com.au/~skaller Glebe 2037 NSW AUSTRALIA
1.5.2 for: else: [ In reply to ]
On Fri, 30 Jul 1999 02:40:42 GMT, wtanksle@dolphin.openprojects.net (William Tanksley) wrote:

>On Wed, 28 Jul 1999 16:38:24 -0500, Gordon McMillan wrote:
>
>try:
> for x in list:
> if iffers(x): raise "no!"
> yadda(x)
>except "no!": pass
>else:
> twiddle()

Not guarranteed to work. Try instead:

exc = "no!"
... raise exc
..
except exc: ..

Python requires the object of a raise to be the same object
as that in the except clause: it is not enough for them to
compare equal as values. Your example only works because
python interns string constants; an implementation detail.

My python interpreter doesn't intern string constants.
The code above will still work, but only because I have extended
the semantics to allow matching by value (which will break
some technically correct python codes).

John Max Skaller ph:61-2-96600850
mailto:skaller@maxtal.com.au 10/1 Toxteth Rd
http://www.maxtal.com.au/~skaller Glebe 2037 NSW AUSTRALIA
1.5.2 for: else: [ In reply to ]
On Wed, 28 Jul 1999 14:57:55 -0700, "Vadim Chugunov" <chega_@yahoo.com> wrote:

>When I first saw Python syntax for loops I said: "A-ha! So in Python I will not
>need a goto
>in situations like this:
>-----
>for(Item* pitem=pseq->First(); pitem; pitem=pitem->Next())
> if (pitem->key==42)
> goto Found;
>
>pitem = pseq->Insert(new Item());
>Found:
> // use item pointed to by pitem
>-----
>In fact, I do not see any other good use for else: clause in a loop.

Isn't this a fine reason for it?
John Max Skaller ph:61-2-96600850
mailto:skaller@maxtal.com.au 10/1 Toxteth Rd
http://www.maxtal.com.au/~skaller Glebe 2037 NSW AUSTRALIA

1 2  View All