PEP-0315--Enhanced While Loop: An idea for an alternative syntax

A

Andrew Koenig

PEP 315 suggests that a statement such as

do:
x = foo()
while x != 0:
bar(x)

be equivalent to

while True:
x = foo()
if x == 0:
break
bar(x)

I like the overall idea, but wonder about the extra keyword. Moreover, if
you see

x = foo()
while x != 0:
bar(x)

you have to read backward to see whether the assignment to x is part of this
statement or part of a previous statement.

I have a proposal for an alternative syntax that solves both of these
problems:

while:
x = foo()
and while x != 0:
bar(x)

This example actually incorporates two changes:

1) "while:" is equivalent to "while True:"

2) "and while <condition>:" is an exit from the middle of the loop,
analogously to PEP 315.

My proposal allows for multiple exits in the obvious way

while <condition 1>:
<statements 1>
and while <condition 2>:
<statements 2>
and while <condition 3>:
<statements 3>
...

in which all of the conditions and statements are evaluated in the order
shown until a condition is false, at which point the loop terminates.


It also occurs to me that this notion can be generalized to include "or
while" as well as "and while". Using "or while" would implement a control
structure that Dijkstra proposed in "A Discipline of Programming". The idea
would be that

while <condition 1>:
<statements 1>
or while <condition 2>:
<statements 2>
or while <condition 3>:
<statements 3>

would be equivalent to

while True:
if <condition 1>:
<statements 1>
elif <condition 2>:
<statements 2>
elif <condition 3>:
<statements 3>:
else:
break

This notion is still partly baked, if for no other reason than that I'm not
sure how a statement with both "or while" and "and while" clauses should
work. My first thought is for "and while" to have priority over "or while",
analogously with expressions, but then the following example came to me.
It's the inner loop of a binary search:

while low < hi:
mid = (low + hi) // 2;
and while value < table[mid]:
high = mid
or while value > table[mid]
low = mid

If "and" has higher precedence than "or", this example doesn't work. So I'm
not sure about its merits -- but I'm mentioning it in case someone else can
improve on it.
 
P

Paul Rubin

Andrew Koenig said:
PEP 315 suggests that a statement such as

do:
x = foo()
while x != 0:
bar(x)

I'm still scratching my head over that PEP. Got a real-world code sample
that it would improve?
 
E

Erik Max Francis

Paul said:
I'm still scratching my head over that PEP. Got a real-world code
sample
that it would improve?

do:
line = inputFile.readline()
while line:
...
line = inputFile.readline()
 
E

Erik Max Francis

Erik said:
do:
line = inputFile.readline()
while line:
...
line = inputFile.readline()

Man, what a perfect gaffe on my part. The purpose of the do...while
construct is to _eliminate_ the duplication. This should be:

do:
line = inputFile.readline()
while line:
...
 
P

Paul Rubin

Erik Max Francis said:
do:
line = inputFile.readline()
while line:
...
line = inputFile.readline()

So it's yet another workaround for Python's lack of assignment
expressions. I like

while (line := inputFile.readline()):
...

a lot better.
 
E

Erik Max Francis

Paul said:
So it's yet another workaround for Python's lack of assignment
expressions. I like

while (line := inputFile.readline()):
...

a lot better.

(Please check my correction, it's actually not as dumb as I suggested.)
 
P

Paul Rubin

Erik Max Francis said:
Man, what a perfect gaffe on my part. The purpose of the do...while
construct is to _eliminate_ the duplication. This should be:

do:
line = inputFile.readline()
while line:
...

I still like the assignment expression better.
 
J

John Roth

Paul Rubin said:
So it's yet another workaround for Python's lack of assignment
expressions. I like

while (line := inputFile.readline()):
...

a lot better.

It may go better in this instance, but assignment in expressions
does nothing for multi-line initialization/reinitialization constructs.

John Roth
 
A

Andrew Koenig

Paul Rubin said:
So it's yet another workaround for Python's lack of assignment
expressions. I like

while (line := inputFile.readline()):
...

a lot better.

I don't, because it limits what is done before the test to a single
expression.

This PEP is really a generalization of the "while (cond) expr" and "do expr
while(cond);" statements in C. C allows the loop exit to be one expression
away from the beginning or one expression away from the end of the loop;
this PEP would allow it anywhere.
 
A

Andrew Koenig

I'm still scratching my head over that PEP. Got a real-world code sample
that it would improve?

Any loop that is currently written in the form

while True:
<statements>
if condition:
break
more statements
 
S

Stefan Axelsson

Just do it with generators:
for line in iter(inputFile.readline, ""):

Or since there's already a tp_iter slot that does that in files these
days:

for line in inputFile:
#do stuff

I'm on the side of the argument that says more interators/generators
than 'funny' looping constructs. Most if not all of the examples I've
seen so far could be written with a generator/iterator to good
effect. It's higher level and clearer code; more Pythonic IMHO.

Stefan,
 
A

Andrew Clover

Andrew Koenig said:
while:
x = foo()
and while x != 0:
bar(x)

This is the best syntax I've seen suggested so far. Tentatively +1
(shouldn't cause any parser difficulties should it?); the lack of new
keywords is a plus too.
'or while' -
while True:
if <condition 1>:
<statements 1>
elif <condition 2>:
<statements 2>

Shouldn't this logically be 'else while' then? 'or while' would imply to
me that there was fall-through from <statements 1> to <statements 2>. I
suppose 'else while' could cause confusion with Python's while...else
construct though.

Not sure this would see a lot of use; I can't think of the last time I used
a structure like that.

Here's another construct suggested by 'and while':

if x is not None:
x.connect()
q= x.fetch()
and if len(q)>=1:
a= q[0]
else:
raise Foo() # one of the previous conditions was False
 
P

Paul Rubin

Andrew Koenig said:
Any loop that is currently written in the form

while True:
<statements>
if condition:
break
more statements

If the loop is complicated enough, it's probably easier to just write
it the way you've written it there. If it's uncomplicated, there's
probably a way to do it with iterators, assignment expressions, or
whatever. Got a real world example that really benefits from the new
construction?
 
G

Guest

while:
x = foo()
and while x != 0:
bar(x)

This example actually incorporates two changes:

1) "while:" is equivalent to "while True:"

2) "and while <condition>:" is an exit from the middle of the loop,
analogously to PEP 315.

How about "until" instead of "and while not", shorter and not new in the
programing languages.

while:
x = foo()
until x == 0:
bar(x)
 
T

Terry Carroll

Hell Erik,

Just do it with generators:
for line in iter(inputFile.readline, ""):
...


With read() instead of readline(), then.

I've certainly run into this using urllib2.
 
P

Peter Hansen

Andrew said:
This is the best syntax I've seen suggested so far. Tentatively +1
(shouldn't cause any parser difficulties should it?); the lack of new
keywords is a plus too.

So
while:

is a synonym for

while 1:

in the above, and the line

and while x != 0:

line is basically a synonym for

if x == 0: break

but with the added disadvantages of requiring a syntax change, using
negative logic, and messing with the indentation philosophy in a
non-intuitive way.

Great.

-Peter
 
N

Nicolas Fleury

Andrew said:
PEP 315 suggests that a statement such as

do:
x = foo()
while x != 0:
bar(x)

be equivalent to

while True:
x = foo()
if x == 0:
break
bar(x)

I like the overall idea, but wonder about the extra keyword. Moreover, if
you see

x = foo()
while x != 0:
bar(x)

you have to read backward to see whether the assignment to x is part of this
statement or part of a previous statement.

I have a proposal for an alternative syntax that solves both of these
problems:

while:
x = foo()
and while x != 0:
bar(x)

I like the "while:" and "and while:" syntax, but I think the "or while"
is confusing. I think it's worth an addition to PEP315

However, I remember reading Stroustrup saying he was not using the
do-while at all (maybe in D&E, I'm not sure). Even if I have used
do-while few times, I have the feeling it should not be added to Python
at all, so I guess I'm in fact against PEP315, whatever the syntax. The
reason is, if I say "do that while you're sleeping", is doesn't mean to
me to do it at least once, even if not sleeping. It might explain why
so much people are not using the do-while. This new syntax is
interesting since it changes the vocabulary, but I think it's still
unclear. The if-break method is only one line more (if the break is on
a new line), and is pretty clear in meaning. However, there's things
from C like += that I'm very happy to have in Python and there's still
things I would like to have, like a ?: equivalent with a different
syntax, but that's another story...

Regards,

Nicolas Fleury
 
A

Andrew Koenig

Paul Rubin said:
If the loop is complicated enough, it's probably easier to just write
it the way you've written it there. If it's uncomplicated, there's
probably a way to do it with iterators, assignment expressions, or
whatever. Got a real world example that really benefits from the new
construction?

I think that reserving "break" for abnormal situations makes programs easier
to understand. Therefore, I would like a way of saying that I expect the
normal exit (or exits) from the loop to be in the middle. Whether you
consider this desire to be part of the real world is up to you.
 

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,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top