The rap against "while True:" loops

E

Ethan Furman

Mensanator said:
Duh. I won't write silly code like that either.
If I need more than one loop structure then I'll
do something like

� � while not done_with_this

� � while not done_with_that

Besides, since I _always_ initialize the flag
before entering a loop, the flag can be reused
and doesn't have to be deleted (as long as the
loops aren't nested). And since I don't use goto,
there's no chance the initialization can be avoided.



"Just another line that has to be interpreted later"
is a strange comment in the context of "del done".

I don't believe John is advocating using it, just pointing out that an
extra line is needed -- whether the extra line is "del loop_control_var"
or "loop_control_var = False", it's still an extra line.

Mind you, I'm not saying you should change the way you program as it
seems to work for you, just that there are other ways to write good
clean programs.

~Ethan~
 
M

Mensanator

I don't believe John is advocating using it, just pointing out that an
extra line is needed -- whether the extra line is "del loop_control_var"
or "loop_control_var = False", it's still an extra line.

Mind you, I'm not saying you should change the way you program as it
seems to work for you, just that there are other ways to write good
clean programs.

And I'm not saying John nor the OP should stop
using what works for them. But there are certainly
valid reasons for "don't use while True" to be
on the "Best Practices" list.

After all, how many times hve you put 'break'
in a loop comprehension?
 
M

Mensanator

Heh-heh: When I read this it occurred to me that another way to
start an infinite loop would be to make a post here on this topic.
Looking at the thread so far it appears I was right.

You're not getting away that easy.

What's YOUR opinion of "whilr True"?
 
P

Paul Rubin

Mensanator said:
And I'm not saying John nor the OP should stop using what works for
them. But there are certainly valid reasons for "don't use while
True" to be on the "Best Practices" list.

After all, how many times hve you put 'break' in a loop
comprehension?

<http://okmij.org/ftp/Streams.html#enumerator-stream>:

Towards the best collection traversal interface

"We present a design of the overall optimal collection traversal
interface, which is based on a left-fold-like combinator with
premature termination. The design has been implemented and tested in
practice."
 
S

Steven D'Aprano

And I'm not saying John nor the OP should stop using what works for
them. But there are certainly valid reasons for "don't use while True"
to be on the "Best Practices" list.

"Valid"? Well, maybe. But none of them are convincing to me. The best I
have seen is that loops should have a single entry point and a single
exit point, to make it easier to reason about pre- and post-conditions.
But frankly I'm not convinced that's true -- or at least, multiple exists
shouldn't *necessarily* leader to difficulty in reasoning about the post-
condition.


After all, how many times hve you put 'break' in a loop comprehension?

What's a loop comprehension?

Do you mean *list* comprehensions? List comps aren't supposed to be a
general purpose replacement for for-loops. They are a deliberately cut-
down version which is easier to read, write and execute than a pure
Python for-loop:
from timeit import Timer
Timer("""L = []
.... for i in range(20):
.... L.append(2*i-1)
.... """, '').repeat()
[9.7169408798217773, 9.4620440006256104, 9.4636049270629883]
Timer('[2*i-1 for i in range(20)]', '').repeat()
[5.6287829875946045, 5.8934588432312012, 5.7950780391693115]

But the consequence of that simplicity and speed is that they're not as
general as a for-loop. This was a design decision. But change the design
and you could have something like this:

[expr for name in seq until cond]

which breaks when cond becomes true.
 
P

Paul Rubin

Steven D'Aprano said:
But the consequence of that simplicity and speed is that they're not as
general as a for-loop. This was a design decision. But change the design
and you could have something like this:

[expr for name in seq until cond]

which breaks when cond becomes true.

from itertools import takewhile
xs = [expr(name) for name in takewhile(lambda s: not cond(s), seq)]
 
G

greg

Steven said:
The best I
have seen is that loops should have a single entry point and a single
exit point, to make it easier to reason about pre- and post-conditions.
But frankly I'm not convinced that's true -- or at least, multiple exists
shouldn't *necessarily* leader to difficulty in reasoning about the post-
condition.

It's not all that difficult.

If you have multiple exit conditions tested in different
places, in general each one can have its own associated
loop invariant. Then the postcondition of the loop is

(invariant1 and exitcond1) or (invariant2 and exitcond2) or ...

If that gets you where you want to be, then you're
home and dry.
 
M

Mensanator

Unfortunately, some of them seem to be reasons from
my point of view to put "*do* use while True" on the
"Best Practices" list. �

Really? Which ones?
Some of the constructs you
seem to like ring big alarm bells with me, because
I've found entirely too many bugs hidden by them.

For example?
How many times have you written 20-line list
comprehensions? �

You mean something like this?

p = [''.join
((c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18,c19))
for c0 in a for c1 in a for c2 in a for c3 in a for c4 in a for c5 in
a for c6 in a for c7 in a for c8 in a for c9 in a for c10 in a for c11
in a for c12 in a for c13 in a for c14 in a for c15 in a for c16 in a
for c17 in a for c18 in a for c19 in a if (c1>c0) and (c2>c1) and
(c3>c2) and (c4>c3) and (c5>c4) and (c6>c5) and (c7>c6) and (c8>c7)
and (c9>c8) and (c10>c9) and (c11>c10) and (c12>c11) and (c13>c12) and
(c14>c13) and (c15>c14) and (c16>c15) and (c17>c16) and (c18>c17) and
(c19>c18)]

Actually, I didn't write it, the computer did:

v = ','.join(['c%s' % i for i in r0])
f = ' '.join(['for c%s in a' % i for i in r0])
i = ' and '.join(['(c%s>c%s)' % (j,j-1) for j in r1])
e = ''.join(["p = [''.join((",v,")) ",f," if ",i,"]"])
If the answer is more than zero,
what on earth possessed you to think it was a
good idea? :)

I didn't. It was a feasibility study. But that was
in the days before itertools was upgraded to handle
all the subsets of the Cartesian Product. No need for
such silliness now. And itertools works better.
 
D

Dennis Lee Bieber

You're not getting away that easy.

What's YOUR opinion of "whilr True"?
Uhm... that it isn't valid in any language having English influence
upon it's keywords...

If anything -- I'd suggest a proposal to add a plain loop as a
keyword in Python, whose effect is equivalent to a "while True", but a
break must be used to exit said loop (well, we'll ignore raising an
exception <G>)
 
D

Dennis Lee Bieber

Using break can avoid a lot of complication in loops. There's no need to
force every loop to have a single exit point (or for that matter, for
every function to have a single return). Compare the straightforward
implementation of a simple linear search:
One thing to note is that "break" ONLY exits the innermost loop --
Ada adds the confusion that one could define a label on the loops, and
have the innermost use
exit outer_label [when condition]


THAT I find scary... Since you have to match the label name to
something that occurs somewhere prior to the "exit", and THEN have to
find the end of that loop.
 
M

Marco Mariani

Dennis said:
One thing to note is that "break" ONLY exits the innermost loop --
Ada adds the confusion that one could define a label on the loops, and
have the innermost use
exit outer_label [when condition]


THAT I find scary... Since you have to match the label name to
something that occurs somewhere prior to the "exit", and THEN have to
find the end of that loop.

But we have exceptions. And I know somebody, in other languages, thinks
it's a Best Practice to avoid using exceptions for flow control.

Thankfully, python programmers are less dogmatic, and use whatever makes
sense to use. I hope.
 
T

Tim Rowe

2009/10/11 Philip Semanchuk said:
IMHO, break, goto, etc. have their place, but they're ripe for abuse which
leads to spaghetti code.

Unrestricted goto can leat to spaghetti code, but surely break can't?
AFAICS, any break construct will still be H-K reducible.
 
T

Tim Rowe

2009/10/14 Marco Mariani said:
Dennis said:
       One thing to note is that "break" ONLY exits the innermost loop --
Ada adds the confusion that one could define a label on the loops, and
have the innermost use
       exit outer_label [when condition]


       THAT I find scary... Since you have to match the label name to
something that occurs somewhere prior to the "exit", and THEN have to
find the end of that loop.

But we have exceptions.

So has Ada.
And I know somebody, in other languages, thinks it's
a Best Practice to avoid using exceptions for flow control.

Thankfully, python programmers are less dogmatic, and use whatever makes
sense to use. I hope.

Absolutely. And it doesn't make sense to use exceptions for flow control :)
 
T

TerryP

When all is said and done, is not all looping *basically* equivalent
to something like this?

begin_loop:
unless TEST
goto end_loop
;; loop body here
if TEST
goto begin_loop
end_loop:

Which could likely be used to implement something like:

while TEST:
# loop body here

in any highly expressive language; which in of it self displays
something about Computer Science.


or am I just talking out my ass?



I've watched this thread with some interest, but really it sounds to
me like the metrics are getting rather lax and this will probably end
up on par with a for (i=0; i < count; i++) versus for (i=0; i < count;
i--) discussion. By that, I mean:


Fruitful conversation but there is no one spoon for every bowl.
 
M

Mensanator

� � � � Uhm... that it isn't valid in any language having English influence
upon it's keywords...

Duh. You DO know that 'r' is next to 'e' on the
keyboard?
� � � � If anything -- I'd suggest a proposal to add a plain � �loop � �as a
keyword in Python, whose effect is equivalent to a "while True", but a
break � �must be used to exit said loop (well, we'll ignore raising an
exception <G>)

And what will that accomplish? The problem isn't
using while True, it's the fact that you are
escaping the loop. Best Practice is to EXIT the
loop properly, not escape from it.
 
M

MRAB

Dennis said:
Uhm... that it isn't valid in any language having English influence
upon it's keywords...

If anything -- I'd suggest a proposal to add a plain loop as a
keyword in Python, whose effect is equivalent to a "while True", but a
break must be used to exit said loop (well, we'll ignore raising an
exception <G>)

<bikeshedding>I'd prefer it to be called "repeat".</bikeshedding>
 
E

Ethan Furman

Mensanator said:
Duh. You DO know that 'r' is next to 'e' on the
keyboard?

Not on mine -- it's next to 'o' and 'u'. :) Go Dvorak!
And what will that accomplish? The problem isn't
using while True, it's the fact that you are
escaping the loop. Best Practice is to EXIT the
loop properly, not escape from it.

I don't think anyone's arguing the opposite. What I *am* seeing argued
is if it's the only correct way to do it, and that anyone who does it
any other way is a scoundrel and a knave. ;-)

For what it's worth, most of my loops run to completion, with no sign of
a break anywhere. Some have a break, and use it. Some, even, (dare I
say it?) use break *and* else! And it's awesome! Go Python! :-D

~Ethan~
 
T

Tim Rowe

2009/10/14 Dennis Lee Bieber said:
       If anything -- I'd suggest a proposal to add a plain    loop    as a
keyword in Python, whose effect is equivalent to a "while True", but a
break    must be used to exit said loop (well, we'll ignore raising an
exception <G>)

And with enough static analysis to guarantee that the break will be
reached? I think it would be a bit much to expect Python to solve the
halting problem!
 
J

Jack Norton

kj said:
I'm coaching a group of biologists on basic Python scripting. One
of my charges mentioned that he had come across the advice never
to use loops beginning with "while True". Of course, that's one
way to start an infinite loop, but this seems hardly a sufficient
reason to avoid the construct altogether, as long as one includes
an exit that is always reached. (Actually, come to think of it,
there are many situations in which a bona fide infinite loops
(typically within a try: block) is the required construct, e.g.
when implementing an event loop.)

I use "while True"-loops often, and intend to continue doing this
"while True", but I'm curious to know: how widespread is the
injunction against such loops? Has it reached the status of "best
practice"?

TIA!

kynn
This thread has gotten a lot of posts concerning programming practices
and dogma alike. I'd like to add a personal use of `while True:` that
has nothing to do with either best practices or dogma.
I use python a *lot* to do day-to-day tasks in an engineering lab. I
use it to control, log, or otherwise converse with rs232 based gear, as
well as use it to back up or organize documents, etc... (lo and behold,
I use this scripting language to write little scripts here and there).
Don't get me wrong, I also write full blown control/logging apps with
python, but that is only 10% of my usage.
Whenever I need to quickly log something (serial output of a device)
quickly, I find myself writing this in the python REPL:
import serial
comport = serial.Serial('COMx', timeout=1)
while True:
get = comport.readline()
f.open("blah", 'a')
f.write(get)
f.close()

It is short enough that I don't see the need to write my own module.
Sometimes I even add a little regexp based filtering -- which adds 2
lines total. When I am done logging I just give 'er a CTRL-C and be
done with it. It is also a hell of a lot less buggy and error prone
than hyperterminal, which my boss uses to do the same thing.
I think this is a perfect example of `while True:` that works damn well,
and there isn't anything that can replace its simplicity. Programming
practices be damned, it is invaluable, and I would recommend doing it in
my situation to any person, regardless of programming experience.
Food for thought.

-Jack
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,061
Latest member
KetonaraKeto

Latest Threads

Top