Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PEP 315: Enhanced While Loop

4 views
Skip to first unread message

W Isaac Carroll

unread,
May 2, 2003, 11:47:03 PM5/2/03
to
PEP: 315
Title: Enhanced While Loop
Version: $Revision: 1.1 $
Last-Modified: $Date: 2003/05/02 22:53:32 $
Author: W Isaac Carroll <icar...@pobox.com>
Status: Draft
Type: Standards Track
Content-Type: text/plain
Created: 25-Apr-2003
Python-Version: 2.4
Post-History:


Abstract

This PEP proposes adding an optional "do" clause to the beginning
of the while loop to make loop code clearer and reduce errors
caused by code duplication.


Motivation

It is often necessary for some code to be executed before each
evaluation of the while loop condition. This code is often
duplicated outside the loop, as setup code that executes once
before entering the loop:

<setup code>
while <condition>:
<loop body>
<setup code>

The problem is that duplicated code can be a source of errors if
one instance is changed but the other is not. Also, the purpose
of the second instance of the setup code is not clear because it
comes at the end of the loop.

It is possible to prevent code duplication by moving the loop
condition into a helper function, or an if statement in the loop
body. However, separating the loop condition from the while
keyword makes the behavior of the loop less clear:

def helper(args):
<setup code>
return <condition>

while helper(args):
<loop body>

This last form has the additional drawback of requiring the loop's
else clause to be added to the body of the if statement, further
obscuring the loop's behavior:

while True:
<setup code>
if not <condition>: break
<loop body>

This PEP proposes to solve these problems by adding an optional
clause to the while loop, which allows the setup code to be
expressed in a natural way:

do:
<setup code>
while <condition>:
<loop body>

This keeps the loop condition with the while keyword where it
belongs, and does not require code to be duplicated.


Syntax

The syntax of the while statement

while_stmt : "while" expression ":" suite
["else" ":" suite]

is extended as follows:

while_stmt : ["do" ":" suite]
"while" expression ":" suite
["else" ":" suite]


Semantics of break and continue

In the do-while loop the break statement will behave the same as
in the standard while loop: It will immediately terminate the loop
without evaluating the loop condition or executing the else
clause.

A continue statement in the do-while loop will behave somewhat
differently than in the standard while loop. Instead of jumping
back to the loop condition, it will jump to the beginning of the
first suite of the loop. This is to ensure that the setup code
has a chance to do its job before the condition is evaluated.


Future Statement

Because of the new keyword "do", the statement

from __future__ import do_while

will initially be required to use the do-while form.


Implementation

The first implementation of this PEP can compile the do-while loop
as an infinite loop with a test that exits the loop.


Copyright

This document is placed in the public domain.


Ben Allfree

unread,
May 3, 2003, 12:23:25 AM5/3/03
to
Can you provide an example snippit?

I'm interested, but I can't come up with a scenario where the loop couldn't
be rewritten, except for do..until loops that must execute at least once,
which require the first loop iteration to be placed before a while loop.

And for that scenario, I would propose a simple "until" loop construct that
is guaranteed to execute once before evaluation:

# Old way
MakeMoney()
while Poor():
MakeMoney()

# New way
until not Poor():
MakeMoney()

The above example assumes one must MakeMoney() before running the Poor()
test ;)

Python programmers would just have to understand that the "until" construct
executes once before evaluation. Or maybe it could be named something more
obvious. "AfterWhile" - heh - no pun intended.

> --
> http://mail.python.org/mailman/listinfo/python-list


Dirk Gerrits

unread,
May 3, 2003, 4:09:53 AM5/3/03
to
Ben Allfree wrote:
> Can you provide an example snippit?

I was just doing this yesterday:

print "Type 'exit' to quit..."
line = raw_input("> ")
while line != "exit":
process_line(line)
line = raw_input("> ")

With the new PEP it would look like this, I think:

print "Type 'exit' to quit..."
do:
line = raw_input("> ")
while line != "exit":
process_line(line)

Of course, I only had one line of setup code so the PEP didn't actually
shorten it a lot, but I can imagine what this would do to bigger examples.

I rather like it.

Dirk Gerrits

Alex Martelli

unread,
May 3, 2003, 5:06:04 AM5/3/03
to
Ben Allfree wrote:

> Can you provide an example snippit?
>
> I'm interested, but I can't come up with a scenario where the loop
> couldn't be rewritten, except for do..until loops that must execute at
> least once, which require the first loop iteration to be placed before a
> while loop.

Those "can be rewritten" too, of course.

In general, the proposed syntax:

do:
setup
while condition:
remainder

has exactly the same semantics as:

while True:
setup
if not condition: break
remainder

so the rewrite is always trivially easy. The PEP claims the current
form is unreadable -- and that syntax-sugar issue is all that needs
to be discussed (as well as choice of new keyword -- if the new PEP
was accepted I'd rather have the more readable 'loop' instead of
the totally obscure 'do').


> And for that scenario, I would propose a simple "until" loop construct
> that is guaranteed to execute once before evaluation:
>
> # Old way
> MakeMoney()
> while Poor():
> MakeMoney()
>
> # New way
> until not Poor():
> MakeMoney()

Rewritable as:

while True:
MakeMoney()
if not Poor(): break

> The above example assumes one must MakeMoney() before running the Poor()
> test ;)
>
> Python programmers would just have to understand that the "until"
> construct executes once before evaluation. Or maybe it could be named
> something more obvious. "AfterWhile" - heh - no pun intended.

I find myself quite grateful that the designer of Python will never
allow anything as absurd as your proposal -- an unreadable "backwards"
ordering (condition appears before but is tested after) AND a new
keyword, all to "solve" *HALF* of an (arguable) problem, when it's
just as easy, as the PEP shows, to solve ALL of it WITHOUT imposing
"out of order" sequencing of source code vs execution order!


Alex

Dan Bishop

unread,
May 3, 2003, 5:36:43 AM5/3/03
to
"Ben Allfree" <ben...@bldigital.com> wrote in message news:<mailman.1051935786...@python.org>...

> Can you provide an example snippit?
>
> I'm interested, but I can't come up with a scenario where the loop couldn't
> be rewritten, except for do..until loops that must execute at least once,
> which require the first loop iteration to be placed before a while loop.

After grepping through a few thousand lines of Python code, I found
only one use of the "while 1"..."break" construct (which I assume is
what do...while intends to replace), which was the main loop in my
text adventure game.

while 1:
# ...
if not getYN("You are now dead. Would you like to play again
(Y/N)?"):
break
if getYN("Would you like to read the intro again (Y/N)?"):
intro()

I'm not sure what the equivalent do...while loop would be.



> And for that scenario, I would propose a simple "until" loop construct that
> is guaranteed to execute once before evaluation:
>
> # Old way
> MakeMoney()
> while Poor():
> MakeMoney()
>
> # New way
> until not Poor():
> MakeMoney()
>
> The above example assumes one must MakeMoney() before running the Poor()
> test ;)
>
> Python programmers would just have to understand that the "until" construct
> executes once before evaluation. Or maybe it could be named something more
> obvious. "AfterWhile" - heh - no pun intended.

TI-8x BASIC (the only language I know of that puts posttest loop
conditions at the beginning) uses

:Repeat not Poor()
:MakeMoney
:End

(Actually, this isn't valid code, because there are no user-defined
functions and no identifiers longer than 8 chars, but this is
irrelevant.)

In future Python, this could be written

repeat not Poor():
MakeMoney()

My personal preferred syntax is

posttest while Poor():
MakeMoney()

John Roth

unread,
May 3, 2003, 6:33:51 AM5/3/03
to

"W Isaac Carroll" <icar...@pobox.com> wrote in message
news:mailman.1051933692...@python.org...

> PEP: 315
> Title: Enhanced While Loop
> Version: $Revision: 1.1 $
> Last-Modified: $Date: 2003/05/02 22:53:32 $
> Author: W Isaac Carroll <icar...@pobox.com>
> Status: Draft
> Type: Standards Track
> Content-Type: text/plain
> Created: 25-Apr-2003
> Python-Version: 2.4
> Post-History:

Frankly, this doesn't do nearly enough to make me interested in
cluttering
the language, and the "if <condition>: break" figure is sufficiently
well
entrenched in a ***lot*** of languages that it's hardly a problem. As
long as a loop starts with "while 1:" or "while True:", you expect to
see
a break and look for it.

-1

John Roth


Ben Allfree

unread,
May 3, 2003, 10:53:43 AM5/3/03
to
At least one other person sees the sense in what I was suggesting :)

At one point, quite a few BASIC and Pascal flavors had a repeat..until or
do..while loop construct. It seems that it faded away, and I'm not sure why.

"posttest while" is as good as anything. It introduces only one key word, is
clear, and doesn't force the looping construct to be split into separate
blocks. Part of the elegance of Python is that the indentation level tells a
lot about the execution path. The do/while PEP would break that rule.

> -----Original Message-----
> From: python-l...@python.org [mailto:python-l...@python.org]

> --
> http://mail.python.org/mailman/listinfo/python-list


Courageous

unread,
May 3, 2003, 1:03:12 PM5/3/03
to

>Abstract
>
> This PEP proposes adding an optional "do" clause to the beginning
> of the while loop to make loop code clearer and reduce errors
> caused by code duplication.

Enough of these requests get satisfied, we may as well go to committee.
Python will be dead by then, even if all involved don't really know it.
The kitchen sink hits the language with a loud clank, bounces around,
everyone dodges, flees the neighborhood.

Python ain't broken. Please don't fix it.

C//

Jordan McCoy

unread,
May 3, 2003, 12:39:37 PM5/3/03
to
The main issue I find with the proposed syntax is that it misrepresents
the purpose of <setup code>. Reference:

> This PEP proposes to solve these problems by adding an optional
> clause to the while loop, which allows the setup code to be
> expressed in a natural way:
>
> do:
> <setup code>
> while <condition>:
> <loop body>
>
> This keeps the loop condition with the while keyword where it
> belongs, and does not require code to be duplicated.

My immediate intuition, when presented with the above syntax, is to
assume that the actual logic of the loop occurs in <setup code>, for two
reasons:

1. It follows from the meaning of 'do' and 'while': "I'm eating lunch
('do') while the diner is serving it ('while')." The above syntax
corresponds with: "I'm in the diner ('do'), while they are serving lunch
('while') and I'm eating lunch ('loop body')." The second example makes
sense, but the first one is more intuitive and natural.

2. Most major languages that implement a post-test loop include the
<loop body> between 'do' and 'while' (or their equivalents). People new
to Python but familar with such languages will expect this.

A closer examination of the code in <setup code> and <loop body> will of
course indicate what is happening. But why create dissonance? My
suggestion would be to use another word, perhaps 'with':

with:


<setup code>
while <condition>:
<loop body>

and perhaps:

with:
<setup code>
do:
<loop body>
while <condition>

I also liked the posttest suggestion, as it keeps the loop condition on
top and clearly indicates the behavior of the loop. Though, in the
interest of completeness, I would suggest an optional, default 'pretest'
keyword as well. So we would have:

with:
<setup code>
posttest while <condition>:
<loop body>

I tend to agree with most of the other posters in that this possibly
adds nice but probably unnecessary syntax and may have indention-flow
implications. Further, 'with' may not be the best word either. However,
I prefer clean, intuitive language constructs where necessary, even if
duplicative of certain uses of other constructs, as I believe it
increases readability and makes the behavior of the code more apparent
and elegant.

Explicitly indicating the setup code of a loop appears worthwhile; I
just don't think 'do' indicates this behavior.

--
Jordan McCoy
(jor...@uts.cc.utexas.edu)


Steven Taschuk

unread,
May 3, 2003, 1:07:04 PM5/3/03
to
Quoth W Isaac Carroll:

> PEP: 315
> Title: Enhanced While Loop

Excellent! Whatever the outcome, this frequent request certainly
deserves a PEP.

[...]


> Syntax
>
> The syntax of the while statement
>
> while_stmt : "while" expression ":" suite
> ["else" ":" suite]
>
> is extended as follows:
>
> while_stmt : ["do" ":" suite]
> "while" expression ":" suite
> ["else" ":" suite]

Consider this code:

do:
foo()
while bar():
snee()
while quux():
fnord()

How many loops is that? According to the syntax above, it's two.
But I think some readers might expect it to be one, like this:

while 1:
foo()
if not bar():
break
snee()
if not quux():
break
fnord()

Of course, if the syntax were extended to allow multiple while
clauses, so that this latter interpretation became correct, then
there would arise the problem of what to do when you *did* want
two loops. You'd have to add a pass statement:

do:
foo()
while bar():
snee()
pass
while quux():
fnord()

(Or "else: pass" or "do: pass" in the same place, for example.)

This is not appealing, so we return to the original, where each do
has exactly one while, and there is possible confusion about the
associations of subsequent whiles.

This confusion can arise because in the proposed syntax, we have a
keyword -- while -- which can occur both to introduce the first
clause of a statement, and to introduce the last clause of a
multiclause statement. No other keyword has this property.

For another example of why this is undesirable: suppose you have a
file open in your text editor and the first line on the screen
starts with while. Is there more to the loop off the top of the
screen? You don't know. Again, no other clause-starting keyword
leaves you in doubt: as things stand now, if, while, for, def, and
class always start statements, and elif, else, except, and finally
always continue them.

This argument suggests that we should use something other than
'while' here. Suppose, for example, that we use 'break if' (and
reverse the meaning of the condition). Then we have

do:
foo()
break if not bar():
snee()
break if not quux():
fnord()

This does away with the ambiguities, and gets us multiple
breakouts pretty much for free.

The reader no doubt anticipates my next step, which is to wonder
why we're introducing a new keyword, 'do'. Why not:

while:
foo()
break if not bar():
snee()
break if not quux():
fnord()

In this version the syntactic sugar is particularly transparent.
I do not see that this is appreciably clearer than the presently
idiomatic form, with if ...: break. The alignment of the breaks
with the while is kind of neat, but imho it's not worth changing
the language.

--
Steven Taschuk stas...@telusplanet.net
"I'm always serious, never more so than when I'm being flippant."
-- _Look to Windward_, Iain M. Banks

Steven Taschuk

unread,
May 3, 2003, 1:16:13 PM5/3/03
to
Quoth Dan Bishop:
[...]

> while 1:
> # ...
> if not getYN("You are now dead. Would you like to play again
> (Y/N)?"):
> break
> if getYN("Would you like to read the intro again (Y/N)?"):
> intro()
>
> I'm not sure what the equivalent do...while loop would be.

This, I presume:

do:
...
yn = getYN("You are now dead...")
while not yn:
if getYN("Would you like..."):
intro()
...

--
Steven Taschuk 7\ 7'Z {&~ .
stas...@telusplanet.net Y r --/hG-
(__/ )_ 1^1`

Steven Taschuk

unread,
May 3, 2003, 1:14:05 PM5/3/03
to
Quoth Ben Allfree:
[...]

> # New way
> until not Poor():
> MakeMoney()
[...]

> Python programmers would just have to understand that the "until" construct
> executes once before evaluation. Or maybe it could be named something more
> obvious. "AfterWhile" - heh - no pun intended.

I have to agree with Alex here: Ick. My expectation on seeing
until foo():
bar()
is that it would be equivalent to
while not foo():
bar()
The proposed out-of-order execution is a recipe for confusion,
imho.

--
Steven Taschuk stas...@telusplanet.net
"Telekinesis would be worth patenting." -- James Gleick

Ben Allfree

unread,
May 3, 2003, 4:08:34 PM5/3/03
to
But both of you are getting caught up in the name I chose rather than the
concept of introducing a single new loop construct that somehow clearly
indicates that the exit test will be performed after the loop body has
executed once.

> -----Original Message-----
> From: python-l...@python.org [mailto:python-l...@python.org]
> On Behalf Of Steven Taschuk
> Sent: Saturday, May 03, 2003 10:14 AM
> To: 'Python List'
> Subject: Re: PEP 315: Enhanced While Loop
>

> --
> http://mail.python.org/mailman/listinfo/python-list


Jp Calderone

unread,
May 3, 2003, 5:41:37 PM5/3/03
to
On Sat, May 03, 2003 at 05:03:12PM +0000, Courageous wrote:
>
> Enough of these requests get satisfied, we may as well go to committee.
> Python will be dead by then, even if all involved don't really know it.
> The kitchen sink hits the language with a loud clank, bounces around,
> everyone dodges, flees the neighborhood.
>
> Python ain't broken. Please don't fix it.

Python is broken. Just not in this respect <0.25 wink>

Jp

--
It is practically impossible to teach good programming style to
students that have had prior exposure to BASIC: as potential
programmers they are mentally mutilated beyond hope of
regeneration. -- Dijkstra
--
up 1 day, 18:38, 8 users, load average: 0.05, 0.06, 0.08

Scott Chapman

unread,
May 3, 2003, 5:01:23 PM5/3/03
to
On Friday 02 May 2003 21:23, Ben Allfree wrote:
> Can you provide an example snippit?
>
> And for that scenario, I would propose a simple "until" loop construct that
> is guaranteed to execute once before evaluation:
>
> # Old way
> MakeMoney()
> while Poor():
> MakeMoney()
>
> # New way
> until not Poor():
> MakeMoney()
>
> The above example assumes one must MakeMoney() before running the Poor()
> test ;)
>
> Python programmers would just have to understand that the "until" construct
> executes once before evaluation. Or maybe it could be named something more
> obvious. "AfterWhile" - heh - no pun intended.

I like the clean syntax of this suggestion but I see two problems with it:

1) It doesn't handle the same case that the PEP proposed syntax handles:

until not Poor():
MakeMoney()
SpendMoney()

SpendMoney() would have to check for not Poor() before spending. This is a
dependency that is totally unacceptable.

PEP syntax would work (if I understand it correctly):

do:
MakeMoney()
while not Poor():
SpendMoney()

2) Making anything that Python programmers would "just have to understand" is
not Pythonesque and should be avoided.

The PEP proposed syntax is far too unclear as well, requiring that the Python
programmer "just understand" that both MakeMoney and SpendMoney are executed
each iteration through the loop.

The syntax seems to say that SpendMoney is the only thing executed through
each iteration.

For instance, the question of which comes first, MakeMoney or SpendMoney, in
the loop execution is not clear.

I would vote for no change to the language before adding this confusing syntax
to it or the alternative proposal. If a clean, straightforward syntax can be
created, great. These seem to me to violate the Zen of Python.

Cordially,
Scott


Ben Allfree

unread,
May 3, 2003, 5:24:05 PM5/3/03
to
> PEP syntax would work (if I understand it correctly):
>
> do:
> MakeMoney()
> while not Poor():
> SpendMoney()

Hmm, that could be. I understood the PEP to say that the while condition was
tested after SpendMoney().

> 2) Making anything that Python programmers would "just have to understand"
> is
> not Pythonesque and should be avoided.

I agree that it should be clear or not implemented. I meant that as
programmers, Python programmers must understand the difference between a
pretest and a posttest.

> I would vote for no change to the language before adding this confusing
> syntax
> to it or the alternative proposal. If a clean, straightforward syntax can
> be
> created, great. These seem to me to violate the Zen of Python.

I agree here also. Even the alternative I brought up is not that special and
I've always been content to use a while loop. In fact, it simplifies things
in a certain sense to know that there is only one open ended loop construct.

Istvan Albert

unread,
May 3, 2003, 6:54:38 PM5/3/03
to
Ben Allfree wrote:

> But both of you are getting caught up in the name I chose rather than the
> concept of introducing a single new loop construct that somehow clearly
> indicates that the exit test will be performed after the loop body has
> executed once.

I would argue that the usefulness of such a construct might
be limited. It is nice to have an approach that is
maybe one line shorter but if the price is that you have to introduce
an entirely new syntax I'd pass.

Istvan.

Dan Bishop

unread,
May 3, 2003, 8:09:18 PM5/3/03
to
"Ben Allfree" <ben...@bldigital.com> wrote in message news:<mailman.105197358...@python.org>...
...

> At one point, quite a few BASIC and Pascal flavors had a repeat..until
> or do..while loop construct. It seems that it faded away, and I'm not sure
> why.

Repeat...until is part of Standard Pascal, but hardly anyone uses
Pascal anymore.

For BASIC, the only flavor I've seen that had a posttest loop
construct (other than conditional GOTO) was QBasic, which had a
DO...LOOP block that allowed all 4 possible combinations of
pretest/posttest and WHILE/UNTIL, so your code could have been written

' option 1: pretest WHILE
' This could also be done by the older WHILE...WEND construct
MakeMoney
DO WHILE Poor()
MakeMoney
LOOP

' option 2: pretest UNTIL
MakeMoney
DO UNTIL NOT Poor()
MakeMoney
LOOP

' option 3: posttest WHILE
DO
MakeMoney
LOOP WHILE Poor()

' option 4: posttest UNTIL
DO
MakeMoney
LOOP UNTIL NOT Poor()

While this was a good syntax for a language that delimited blocks with
pairs of statements (e.g., FOR...NEXT, FUNCTION...END FUNCTION),
unfortunately it wouldn't work well in Python.

Personally, I'm satisfied with

rzed

unread,
May 3, 2003, 8:34:16 PM5/3/03
to

"W Isaac Carroll" <icar...@pobox.com> wrote in message
news:mailman.1051933692...@python.org...
> PEP: 315
> Title: Enhanced While Loop
> Version: $Revision: 1.1 $
> Last-Modified: $Date: 2003/05/02 22:53:32 $
> Author: W Isaac Carroll <icar...@pobox.com>
> Status: Draft
> Type: Standards Track
> Content-Type: text/plain
> Created: 25-Apr-2003
> Python-Version: 2.4
> Post-History:
>
>
[...]

>
> This PEP proposes to solve these problems by adding an optional
> clause to the while loop, which allows the setup code to be
> expressed in a natural way:
>
> do:
> <setup code>
> while <condition>:
> <loop body>
>
> This keeps the loop condition with the while keyword where it
> belongs, and does not require code to be duplicated.
>
>

This does not strike me as "natural" in Python. By indenting the code
block as shown, a Python programmer would naturally see two blocks, the
second conditioned by a while statement. The normal logic of a while
would mark it as the loop beginning, not as somewhere in the middle of a
loop.

Even if the indentation were arranged differently, for a programmer
coming from the background of a language with a do ... while (or do ...
until) construct, the spec is not natural. The test would be expected at
the very end of the loop (or would at least be applied at the end of the
loop).

This seems to address a problem that doesn't really exist, and to try to
solve it in a forced manner, with rules that do not work as the rest of
the language does.

The main issue seems not to be the creation of a "do once, then test"
loop, but the elimination of duplicated setup code. That duplication can
happen, once in a great while, but is it really frequent enough, or
serious enough, to drive a syntactic upheaval? There are Pythonic ways
of dealing with the issue, and in the worst case, they include
duplicating the code. What's the big deal? It doesn't happen often and
the existing mechanisms can be used to handle the situation when it
does.

Python doesn't need much sugar to make it go down, and in this case,
it's more a case of syntactic garlic -- great for some, but not for
everyone, and for those who don't use it, it just stinks.

--
rzed


Ben Allfree

unread,
May 3, 2003, 8:24:32 PM5/3/03
to

I agree, that's the way I do it. Although I still need to work the bugs out
of my MakeMoney() implementation.



> Personally, I'm satisfied with
>
> while True:
> MakeMoney()
> if not Poor():
> break

> --
> http://mail.python.org/mailman/listinfo/python-list


Steven Taschuk

unread,
May 4, 2003, 1:46:29 AM5/4/03
to
Quoth Ben Allfree:

> But both of you are getting caught up in the name I chose rather than the
> concept of introducing a single new loop construct that somehow clearly
> indicates that the exit test will be performed after the loop body has
> executed once.

Putting the loop condition *textually before* the loop body
indicates just the contrary. This is my objection (and, I
believe, Alex's), and it has nothing to do with the keyword.

Francis Avila

unread,
May 4, 2003, 1:26:08 PM5/4/03
to

"Steven Taschuk" <stas...@telusplanet.net> wrote in message
news:mailman.1051981266...@python.org...

> Quoth W Isaac Carroll:
> > PEP: 315
> > Title: Enhanced While Loop


I must agree with the general concensus on 'do...while'. It's hardly ever
needed, it's unpythonic, it's confusing, and it can be delt with by other
more straightforward methods. The PEP tersely discusses the infinite loop
alternative last, as though it were the ugliest and worst of the
alternatives to 'do' that he listed, when in fact (as Alex Martelli
mentioned), it is by far the clearest and most straightforward alternative,
and even easier to grep than 'do..while', because the indentation is more
natural and the code is executed in order.

(Although I understand that infinite loops seem to be reguarded by many
zelots as the moral equivalent of global variables.)

But just to throw in my two cents, I think the following good suggestion can
be made better:

> The reader no doubt anticipates my next step, which is to wonder
> why we're introducing a new keyword, 'do'. Why not:
>
> while:
> foo()
> break if not bar():
> snee()
> break if not quux():
> fnord()
>
> In this version the syntactic sugar is particularly transparent.
> I do not see that this is appreciably clearer than the presently
> idiomatic form, with if ...: break. The alignment of the breaks
> with the while is kind of neat, but imho it's not worth changing
> the language.

This is very verbose, has a somewhat unnatural indentation (it seems like
'break' is outside the while loop), and retains the negation of the
condition, which can often lead to confusion.

while:
[do:] # Notice that this makes things clearer, but is redundant.
<setup code>
[then] if <condition>: # Same here; 'then' is not strictly needed.
<loop body>


Advantages: the entire loop is in a separate code block, the code is
executed in order, and the condition doesn't have to be negated for the
logic to work, unlike with an infinite while loop.

Disadvantages: it is verbose, and there are *two* new keywords! However,
strictly speaking no keywords need to be added at all, although it is far,
far more understandable when the setup code is explicit. Compare:

while:
<setup code>
if <condition>:
<loop body>
[else: break] # This is implicit...
if <condition>:
<loop body continues>

This does the same thing, although without the indentation of setup code it
is less natural. Also, it's easy for someone who first sees this syntax to
think that a bare 'while:' is the same as 'while True:', although 'while:'
currently raises SyntaxError, and could be easily extended to have the above
meaning.

The biggest disadvantage is that it's not crystal clear that the while loop
will break if <condition> is false, and that subsequent 'if' blocks won't
get executed (this is the big advantage of Steven's syntax, where the break
is made explicit.) If you want every condition in the loop to be tested,
without breaking, you'd need to do:

while:
<setup>
if <condition>:
<loop body>
elif <condition>:
<alternate loop body>
else:
<third alternate loop body>

Frankly, I can't think of any use case for this, but you get it for free.

Now that I've whet your appetite, look at this:

while True:
<setup>
if <condition>:
<loop body>
else: break
if <condition>:
<loop continuation>
elif <condition>:
<alternative loop continuation>
elif:
<third alternative loop continuation>
else: break

The only difference between this *current* syntax and the syntax I proposed
is that this makes explicit what I made implicit. But, as the wise ones say,
"Explicit is better than implicit."[1] Therefore the current syntax is
better than the syntax I proposed. In fact, 'if not <condition>' is simply
a shorthand for 'if <condition>: ... else: break'!

So you see, 'do..while' is essentially an infinite loop anyway! Why hide
it? Why shroud our denial of the plain fact of an infinite loop behind this
cryptic syntax? Rise up, my friends! Wallow in the darkness of denial no
more! Embrace the infinite loop! May all your loops be infinite! 'While
True', 'While True'! Infinite Truth!

(Uh, ahem. Ok, I'm better now. Excuse me.)

[1] Tim Peters, _Zen_of_Python_: http://www.python.org/doc/Humor.html#zen
--
Francis Avila

Terry Reedy

unread,
May 4, 2003, 2:11:24 PM5/4/03
to

"Francis Avila" <franci...@yahoo.com> wrote in message
news:vbajd67...@corp.supernews.com...
....

> The only difference between this *current* syntax and the syntax I
proposed
> is that this makes explicit what I made implicit. But, as the wise
ones say,
> "Explicit is better than implicit."[1] Therefore the current syntax
is
> better than the syntax I proposed. In fact, 'if not <condition>' is
simply
> a shorthand for 'if <condition>: ... else: break'!

My main objection to the current idiom is that it does not visually
separate the preparation and processing parts of the loop -- unless
one trains oneself to more readily 'see' the 'if not: break' as a
break between them. The unshorthad version, with at most one more
word, does this by indenting the process part more than the prep.. I
think I will give it a try. In the meanwhile, I am -1 on the PEP.

Terry J. Reedy


Delaney, Timothy C (Timothy)

unread,
May 4, 2003, 9:06:37 PM5/4/03
to
> From: rzed [mailto:rza...@ntelos.net]

>
> This does not strike me as "natural" in Python. By indenting the code
> block as shown, a Python programmer would naturally see two
> blocks, the
> second conditioned by a while statement. The normal logic of a while
> would mark it as the loop beginning, not as somewhere in the
> middle of a
> loop.

IMO, this is the crux of the argument.

do:
something
while test:
something else

looks like two separate things.

The traditional argument here is

try:
something
except:
something else

But there is a major difference. Once something enters the except: clause, it does not go back to the try: clause. The processing is one-way at the same indentation level.

OTOH, with do: while:, the processing loops back to across the indentation level.

The only way I could see the above being pythonic would be if it were of the form (ignoring existing meanings of such code):

do:

something

while test:
something else

From there it's a short step to

do:

something

if test:
something else

to

while True:

something

if test:
something else

to (if desired)

while True:

something

if not test:
break

something else

There are plenty of other arguments against the proposed syntactic structure (ambiguity, etc) but they've been well-argued.

I vote that the BDFL immediately reject this PEP so that we can put this issue to rest once and for all. That *is* why the PEP was created wasn't it ... to be rejected? ;)

Tim Delaney

W Isaac Carroll

unread,
May 5, 2003, 7:30:04 AM5/5/03
to
Here are my responses to the ideas discussed since I posted PEP 315.

* PEP was submitted to be rejected

If the Python community rejects the PEP so be it, but I really would
like a statement that works like this.

* "Python ain't broken. Please don't fix it."

Python is not broken. But if Python could not be improved we wouldn't
need PEPs at all.

* "do" is unclear
* do-while in other languages doesn't have 2nd suite
* do-while-while ambiguity
* unseen "do" changes the meaning of seen "while"

These are problems which I had not considered when writing the PEP. It
seems to me that the best way to solve them is to choose different
keywords. How about:

perform:
<setup code>
whilst <condition>:
<loop body>

:)

* indentation should indicate execution path
* it's not clear that both blocks execute each iteration

These are good points. There is no precedent in Python for two
indentation groups which are conceptually the same block. Indenting the
while statement to the same level as the rest of the block would solve
this problem but it would hide the loop condition. I prefer the pattern
recommended in the PEP because it clearly indicates the loop condition,
but I do not know for certain that it is better (clearer, more pythonic,
etc).

* a post-test loop is sufficient

The problem I presented in the PEP could not be solved with a post-test
loop. However, please note that a post-test loop could easily be
constructed using the do-while syntax of the PEP.

* infinite loop with break is a well-known idiom in other languages and
is a good way of expressing this behavior

Experienced programmers are used to writing infinite loops and breaking
out of them. However, saying "while True" does not clearly express the
purpose and behavior of the loop. Just because it's traditional to write
infinite loops does not mean that it's a good way to program.

I feel that the use of break is similar to the use of goto in the past.
Goto was necessary because of the limited control structures available
in early languages, but as for, while, if-else, functions, and other
powerful control structures came into use, the goto was no longer
necessary and gradually disappeared. If we adopt loop constructs of
sufficient power and flexibility, the break statement will also no
longer be needed, and will disappear from use.

In other words, if all you have is an infinite loop, everything looks
like it needs one.

If I have not adequately responded to your comment, please re-post it or
send me email.

TTFN


Michael Chermside

unread,
May 5, 2003, 8:59:35 AM5/5/03
to
> [W Isaac Carroll posted PEP 315 (revision 1.1)]

Isaac:

Thanks for the excellently written PEP! There are three minor
changes that I would propose. First, incorporate Alex's
suggestion of "loop" instead of "do" for the introductory
keyword:

loop:
<loop code>
while condition:
<more loop code>

which is (IMHO) quite readable. Secondly, I would suggest
re-ordering the motivation section to stress the particular
existing-syntax-alternative which is most strongly supported
by python experts and PEP opponents. They tend to prefer the
synatx of:

while True:
<loop code>
if not condition: break
<more loop code>

so I would list that alternative first, or perhaps just
indicate in the discussion that it's the syntax preferred by
many in the absense of the PEP. Of course, you should KEEP
the comments about why this solution is not desirable...
after all, this is the MOTIVATION section!

Thirdly, I would suggest that you clearly address the problem
of "dangling while" and specify how it is to be addressed.
Give a specific example like this:

count1 = count2 = 3
loop:
print "A"
while cond1:
cond1 -= 1
print "B"
while cond2:
cond2 -= 1
print "C"

and tell what the output would be. (My proposal would be
"ABABABACCC", but go with whatever solution you like so
long as it's unambiguous.)

Lastly, I would suggest that you _define_ the behavior of
the new construct in terms of existing syntax. Guido likes
that... in fact, in the case of list comprehensions he left
what I would consider a wart (leaving the loop variable
around after completing the comprehension) in order to
exactly conform to the definition he had used). I would
suggest something like this:

The behavior of this construct:
>>> loop:
... <suite 1>
... while <condition>:
... <suite 2>

will be exactly the same as the behavior of
>>> while True:
>>> <suite 1>
>>> if not <condition>: break
>>> <suite 2>

but you'll have to be very careful about handling all
situations including "else" clauses... so I'd probably
add that:

The behavior when an "else" clause is present:
>>> loop:
... <suite 1>
... while <condition>:
... <suite 2>
... else:
... <suite 3>

will be exactly the same as the behavior of

>>> __normal_loop_exit__ = False
>>> while True:
... <suite 1>
... if not <condition>:
... __normal_loop_exit = True
... break
... <suite 2>
>>> if __normal_loop_exit__:
... <suite 3>
>>> del __normal_loop_exit__

*except* for the fact that the variable
"__normal_loop_exit__" will not be visible in any
scope.

Kinda excessive detail for a behavior that's obvious, but
the PEP should spell it out.

Anyway, nice work on this PEP... it's something we've needed
for a long time.


Now for the bad news. I'm -1 on this PEP. I think it should
be rejected, for two reasons: I think the alternative *IS*
sufficiently readable (reasonable people could disagree, but
that's my opinion) and I find newbies tend to write better
code (fewer errors) if they are forced to do their tests at
the top of the loop (which is where the tests belong for the
overwelming majority of loops).

But enough of *MY* reasons... this is a FREQUENT request, and
it deserves a good writeup and evenhanded consideration. If
it's accepted, we'll have a new language feature (and it should
be as well-designed as possible). If it is rejected, at least
what got considered was the very BEST syntax possible.

-- Michael Chermside


Andrew Koenig

unread,
May 5, 2003, 8:52:17 AM5/5/03
to
> Python is not broken. But if Python could not be improved we wouldn't
> need PEPs at all.

Agreed.

> * "do" is unclear
> * do-while in other languages doesn't have 2nd suite
> * do-while-while ambiguity
> * unseen "do" changes the meaning of seen "while"

On the other hand, I proposed essentially the same idea for C back in
1977. Unfortunately, Dennis didn't think it was worth the effort :-)

> These are problems which I had not considered when writing the PEP. It
> seems to me that the best way to solve them is to choose different
> keywords. How about:

> perform:
> <setup code>
> whilst <condition>:
> <loop body>

This is obviously intended to be tongue-in-cheek. However, it does give
me a thought about how to express this notion in a way that is much clearer
and requires no new keywords:

while:
<setup code>
and while <condition>:
<loop body>

Indeed, we can think of this usage as syntactic sugar for the following:

while: ==> while True:

<dedent> and while <condition>: <indent> ==> if not (<condition>): break

By implication, there is no obvious reason that one could not write

while <condition1>:
<code1>
and while <condition2>:
<code2>
and while <condition3>:
<code3>

which would be equivalent to

while <condition1>:
<code1>
if not (<condition2>): break
<code2>
if not (<condition3>): break
<code3>

Looking at these examples, I find myself liking the "and while" idea more,
because it uses (negative) indentation to mark the possible exit points.


--
Andrew Koenig, a...@research.att.com, http://www.research.att.com/info/ark

Oren Tirosh

unread,
May 5, 2003, 10:25:09 AM5/5/03
to
On Mon, May 05, 2003 at 12:52:17PM +0000, Andrew Koenig wrote:
> > Python is not broken. But if Python could not be improved we wouldn't
> > need PEPs at all.
>
> Agreed.
>
> > * "do" is unclear
> > * do-while in other languages doesn't have 2nd suite
> > * do-while-while ambiguity
> > * unseen "do" changes the meaning of seen "while"
>
> On the other hand, I proposed essentially the same idea for C back in
> 1977. Unfortunately, Dennis didn't think it was worth the effort :-)

But C does allow assignment inside expressions, three-way conditionals
and comma as "evaluate both, return right". Together they cover most of
what people might want the "setup" part for.

But adding such features to Python expressions will be quite unpythonic.

> > perform:
> > <setup code>
> > whilst <condition>:
> > <loop body>
>
> This is obviously intended to be tongue-in-cheek. However, it does give
> me a thought about how to express this notion in a way that is much clearer
> and requires no new keywords:
>
> while:
> <setup code>
> and while <condition>:
> <loop body>

Nice. No new keywords. Cannot be easily confused with a C do/while loop.
This probably improves BDFL acceptance factor from -10 to -7 or better!

;-)

Oren

Alex Martelli

unread,
May 5, 2003, 11:55:39 AM5/5/03
to
Andrew Koenig wrote:
...

> clearer and requires no new keywords:
>
> while:
> <setup code>
> and while <condition>:
> <loop body>

Lovely. Best syntax I've seen so far.

> Indeed, we can think of this usage as syntactic sugar for the following:
>
> while: ==> while True:
>
> <dedent> and while <condition>: <indent> ==> if not (<condition>):
> break

OK. Makes the semantic of an else clause somewhat peculiar (the else
clause's body executes if the condition on the FIRST while causes the
exist, but not if the loop exists because of the condition on any of
the FOLLOWING while's) but perhaps that's secondary.

> By implication, there is no obvious reason that one could not write
>
> while <condition1>:
> <code1>
> and while <condition2>:
> <code2>
> and while <condition3>:
> <code3>

Yes, this generality would help.

> which would be equivalent to
>
> while <condition1>:
> <code1>
> if not (<condition2>): break
> <code2>
> if not (<condition3>): break
> <code3>
>
> Looking at these examples, I find myself liking the "and while" idea more,
> because it uses (negative) indentation to mark the possible exit points.

I do agree the outdents make the structure clearer -- indeed, that's
essentially THE point. I think this proposal should go in the PEP --
it does not suffer disadvantages such as new keyword introduction.


Alex

Andrew Koenig

unread,
May 5, 2003, 11:11:26 AM5/5/03
to
>> On the other hand, I proposed essentially the same idea for C back in
>> 1977. Unfortunately, Dennis didn't think it was worth the effort :-)

Oren> But C does allow assignment inside expressions, three-way conditionals
Oren> and comma as "evaluate both, return right". Together they cover most of
Oren> what people might want the "setup" part for.

Yes.

Oren> But adding such features to Python expressions will be quite unpythonic.

Let's not talk about PEP308, OK?

>> while:
>> <setup code>
>> and while <condition>:
>> <loop body>

Oren> Nice. No new keywords. Cannot be easily confused with a C do/while loop.
Oren> This probably improves BDFL acceptance factor from -10 to -7 or better!

That's my guess too.

I must confess that I find this issue less important now that we have
generators. Before that, I was looking for a clean way of writing

while True:
line = infile.read()
if not line:
break
<process a line>

but with generators it is possible to write

for line in infile:
<process a line>

(Yes, I know that you don't need generators to allow such usages for
built-in types, but generators make it much easier to do similar things
with user-defined types)

Dirk Gerrits

unread,
May 5, 2003, 10:44:47 AM5/5/03
to
I already expessed that I like the general idea of the proposed
construct. But I agree with others that the proposed syntax is not too
clear.

Andrew Koenig wrote:
> By implication, there is no obvious reason that one could not write
>
> while <condition1>:
> <code1>
> and while <condition2>:
> <code2>
> and while <condition3>:
> <code3>
>

[snip]


>
> Looking at these examples, I find myself liking the "and while" idea more,
> because it uses (negative) indentation to mark the possible exit points.

This on the other hand seems to express the intent a lot better. Great
idea Andrew! FWIW, I'm +1 on this.

Regards,
Dirk Gerrits

Dave Benjamin

unread,
May 5, 2003, 12:04:52 PM5/5/03
to
In article <vbajd67...@corp.supernews.com>, Francis Avila wrote:
> I must agree with the general concensus on 'do...while'. It's hardly ever
> needed, it's unpythonic, it's confusing, and it can be delt with by other
> more straightforward methods.

Your use of the word "unpythonic" is particularly baffling in this context.
I'm not sure what the official definition of "pythonic" is, but it would
seem that "pythonic" is how one might go about doing things in Python
(the one obvious way to do it, of course). The very nature of a PEP is to
redefine the Python language in some way, and therefore, redefine "pythonic"
and "unpythonic" as well.

To condemn a change in a change in a language because it would result in a
usage different from how the language is currently used is just circular
logic. Not picking a fight, just an observation. ;)

Dave

Daniel Fackrell

unread,
May 5, 2003, 12:23:09 PM5/5/03
to
"Dave Benjamin" <ra...@lackingtalent.com> wrote in message
news:slrnbbd2uq...@lackingtalent.com...

In case it might help, this is from PEP 1:

'''
Finally, a proposed enhancement must be "pythonic" in order to be accepted
by the BDFL. (However, "pythonic" is an imprecise term; it may be defined
as whatever is acceptable to the BDFL. This logic is intentionally
circular.)
'''

--
Daniel Fackrell (newsgrou...@dfackrell.mailshell.com)
When we attempt the impossible, we can experience true growth.


Terry Reedy

unread,
May 5, 2003, 12:33:16 PM5/5/03
to

"Andrew Koenig" <a...@research.att.com> wrote in message
news:yu99issp...@europa.research.att.com...

> By implication, there is no obvious reason that one could not write
>
> while <condition1>:
> <code1>
> and while <condition2>:
> <code2>
> and while <condition3>:
> <code3>

To me, this is the best alternative (to the current idiom) so far. No
new keyword, no ambiguity about where block begins and ends. However,
the actual execution flow is still not necessarily clear. Reading
this naively, I would expect the loop to continue, and <code1> to
continue to be executed, until <condition1> was false. Or something
like that.

> which would be equivalent to
>
> while <condition1>:
> <code1>
> if not (<condition2>): break
> <code2>
> if not (<condition3>): break
> <code3>
>
> Looking at these examples, I find myself liking the "and while" idea
more,
> because it uses (negative) indentation to mark the possible exit
points.

I am beginning to like explicit breaks more.

Terry J. Reedy


Terry Reedy

unread,
May 5, 2003, 12:41:55 PM5/5/03
to

"W Isaac Carroll" <icar...@pobox.com> wrote in message
news:mailman.1052134283...@python.org...

> Here are my responses to the ideas discussed since I posted PEP 315.
>
> * PEP was submitted to be rejected

It was clear to me that you would like acceptance. However, a
rejected PEP that lists several alternatives to the status quo and
their pros and cons will be a service to the community.

...


> I feel that the use of break is similar to the use of goto in the
past.

'Break' and 'continue' are recognized in language design theory as
restricted gotos, as is 'raise x' (or longjump() in C) . They are
practical compromises with structured purity.

Terry J. Reedy


andrew cooke

unread,
May 5, 2003, 12:07:47 PM5/5/03
to

but what does it do? i've not been following this thread and so these are
all "honest" reactions to the syntax:

- if condition1 is true but condition2 is false is code1 repeated?
- what if condition2 is true but condition1 is false?
- is there any meaning for "or while"?
- if condition1 and condition2 are both true do both code1 and code2 get
repeated together, or is nesting implied (does code2 repeat until
condition2 is false then you start with code1 again?)?

these aren't necessaril criticisms - maybe i'd ask similar things about
existing constructs if they were new to me. but it doesn't seem totally
obvious what the answers are (i'm guessing the answers are: yes, nothing,
no, together, but i'm not 100% sure on any of them)

andrew

Dirk Gerrits said:

> I already expessed that I like the general idea of the proposed
> construct. But I agree with others that the proposed syntax is not too
> clear.
>
> Andrew Koenig wrote:

>> By implication, there is no obvious reason that one could not write
>>
>> while <condition1>:
>> <code1>
>> and while <condition2>:
>> <code2>
>> and while <condition3>:
>> <code3>
>>

> [snip]


>>
>> Looking at these examples, I find myself liking the "and while" idea
>> more,
>> because it uses (negative) indentation to mark the possible exit points.
>

> This on the other hand seems to express the intent a lot better. Great
> idea Andrew! FWIW, I'm +1 on this.
>
> Regards,
> Dirk Gerrits
>
>
>

> --
> http://mail.python.org/mailman/listinfo/python-list
>
>


--
http://www.acooke.org/andrew

Evan Simpson

unread,
May 5, 2003, 11:59:51 AM5/5/03
to
Andrew Koenig wrote:
> while:
> <setup code>
> and while <condition>:
> <loop body>

Now, *this* is why we have PEPs! Without them, everything old is new
again, every few years.

See Guido's reaction:

http://groups.google.com/groups?q=g:thl1134131894d&selm=199901042051.PAA20739%40eric.cnri.reston.va.us

See the implementation announcement:

http://groups.google.com/groups?q=g:thl3737064544d&selm=7hsv80%24g9j%241%40news.tamu.edu

I can't for the life of me remember how it died, though.

wow-it's-been-four-years-ly yrs,

Evan @ 4-am

Andrew Koenig

unread,
May 5, 2003, 1:47:01 PM5/5/03
to al...@aleax.it
Alex> OK. Makes the semantic of an else clause somewhat peculiar (the else
Alex> clause's body executes if the condition on the FIRST while causes the
Alex> exist, but not if the loop exists because of the condition on any of
Alex> the FOLLOWING while's) but perhaps that's secondary.

Well, maybe. I hadn't thought of else clauses. Indeed, that may be
another reason for my proposed syntax, because I would certainly want
the else to execute if the condition of *ANY* of the while clauses
causes the exit (but not if a break causes it).

Andrew Koenig

unread,
May 5, 2003, 1:39:40 PM5/5/03
to
Evan> Andrew Koenig wrote:
>> while:
>> <setup code>
>> and while <condition>:
>> <loop body>

Evan> Now, *this* is why we have PEPs! Without them, everything old is new
Evan> again, every few years.

Evan> See Guido's reaction:

Evan> http://groups.google.com/groups?q=g:thl1134131894d&selm=199901042051.PAA20739%40eric.cnri.reston.va.us

Evan> See the implementation announcement:

Evan> http://groups.google.com/groups?q=g:thl3737064544d&selm=7hsv80%24g9j%241%40news.tamu.edu

Evan> I can't for the life of me remember how it died, though.

Evan> wow-it's-been-four-years-ly yrs,

That's hilarious! I had nothing at all to do with Python in 1999, which means
that I came up with the same idea completely independently.

And Guido liked it too! What are we waiting for? :-)


rzed

unread,
May 5, 2003, 3:54:58 PM5/5/03
to

While I agree that this syntax is an improvement over the original PEP
version, it still would create a block structure different from any
other in Python.

Andrew says that this:

> while <condition1>:
> <code1>
> and while <condition2>:
> <code2>
> and while <condition3>:
> <code3>

would be equivalent to this:

>
> while <condition1>:
> <code1>
> if not (<condition2>): break
> <code2>
> if not (<condition3>): break
> <code3>
>

... which means that the first 'while' and the second do not mean the
same thing. That's less than "obvious" (ergo, less than "Pythonic"?).
If "while" does not imply a looping construct, why use the word?
How about:

while <condition1>:
<code1>
and if <condition2>:
<code2>
and if <condition3>:
<code3>

Now the if tests do not imply loops within loops, and because they are
anded (in some vague way), the failure of any of them would break out
of the while loop.

I'd still prefer to see an indention of the entire while block,
though -- it seems more obvious:

while <condition1>:
<code1>
and if <condition2>:
<code2>
and if <condition3>:
<code3>

... or maybe not.

--
rzed


W Isaac Carroll

unread,
May 5, 2003, 3:01:54 PM5/5/03
to
Using the following syntax as the example:

while <condition1>:
<code1>
and while <condition2>:
<code2>
and while <condition3>:
<code3>

My preference is to define the loop as all of the code blocks together,
and treat all the while clauses symmetrically. My original proposal only
allowed one while clause, but I see no particular reason to keep to that
limit. Any CS people know of a reason why multiple loop conditions would
be a bad thing?

andrew cooke wrote:
> - if condition1 is true but condition2 is false is code1 repeated?

No. The loop will exit after finding condition2 to be false.

> - what if condition2 is true but condition1 is false?

The loop will exit after finding condition1 to be false.

> - is there any meaning for "or while"?

The use of "and" is motivated by a desire to not introduce new keywords
into the language. There is no proposed meaning for "or while".

> - if condition1 and condition2 are both true do both code1 and code2 get
> repeated together, or is nesting implied (does code2 repeat until
> condition2 is false then you start with code1 again?)?

No nesting is implied. The loop repeats as long as it finds all
conditions to be true when they are evaluated. The first one found to be
false causes the entire loop to exit, transferring control to the else
clause, if present.

> these aren't necessaril criticisms - maybe i'd ask similar things about
> existing constructs if they were new to me. but it doesn't seem totally
> obvious what the answers are (i'm guessing the answers are: yes, nothing,
> no, together, but i'm not 100% sure on any of them)

Fair enough. Since this construct is not a typical one found in other
languages, no one is expected to immediately know what it does at first
glance. However, I believe that the "and while" syntax is easy enough to
recognize and remember that once people learn its semantics there won't
be any confusion.

TTFN


W Isaac Carroll

unread,
May 5, 2003, 3:25:22 PM5/5/03
to
Alex Martelli wrote:
> I do agree the outdents make the structure clearer -- indeed, that's
> essentially THE point. I think this proposal should go in the PEP --
> it does not suffer disadvantages such as new keyword introduction.

Yes. That is one of the fundamental ideas that I'm shooting for. The
loop condition needs to be clearly visible so the loop's behavior is
clearly understood.

As long as the syntax makes the loop clear the exact spelling doesn't
matter much. I like the "and while" syntax well enough, and it seems to
be an acceptable compromise between clarity and not breaking compatibility.

The only thing that concerns me about the generalized case

while <cond1>:
<block1>
and while <cond2>:
<block2>

is that it has the same problem as was brought up about the do-while
syntax: When a part of the loop is off the screen or on another page,
you might get the wrong idea about the loop. However, if you see
"while:" you know something funny is going on and you can pay closer
attention.

TTFN


Dave Benjamin

unread,
May 5, 2003, 4:07:34 PM5/5/03
to
In article <3eb68...@hpb10302.boi.hp.com>, Daniel Fackrell wrote:
>> To condemn a change in a change in a language because it would result in a
>> usage different from how the language is currently used is just circular
>> logic. Not picking a fight, just an observation. ;)
>
> In case it might help, this is from PEP 1:
>
> '''
> Finally, a proposed enhancement must be "pythonic" in order to be accepted
> by the BDFL. (However, "pythonic" is an imprecise term; it may be defined
> as whatever is acceptable to the BDFL. This logic is intentionally
> circular.)
> '''

Substituting Alex Martelli's definition of Pythonic in that sentence gives
us: "...a proposed enhancement must be of, relating to, or resembling
Python...". This is hopelessly circular, to the point where you can draw no
useful conclusion from that requirement. Even if you acknowledge the
circularity from day (or PEP) one.

Erik Max Francis's definition was a bit easier to incorporate: "...a
proposed enhancement must seem to follow good style laid about by the
language Python...".

So, I guess it all depends on what the word means to you (or to the BDFL,
really). Not to mention your definitions of "good" and "style".

Cheers,
Dave

Alex Martelli

unread,
May 5, 2003, 4:14:01 PM5/5/03
to
W Isaac Carroll wrote:
...

> The only thing that concerns me about the generalized case
>
> while <cond1>:
> <block1>
> and while <cond2>:
> <block2>
>
> is that it has the same problem as was brought up about the do-while
> syntax: When a part of the loop is off the screen or on another page,
> you might get the wrong idea about the loop. However, if you see

No more than you could with the current way of spelling it:

while <cond1>:
<block1>
if not <cond2>:break
<block2>

if you're scrolled so the END of the while's body is not showing, then
you know there MIGHT be exist conditions further down -- nothing new.

The issue with the original proposal's "do ... while cond>" is that you
might have been looking right at the "while cond:" clause AND have no
way to now you should be looking BACKWARDS for a crucial part of the
loop -- THAT would have been a novel trap. But there is nothing like
that in this proposal.


Alex

Steven Taschuk

unread,
May 5, 2003, 4:31:46 PM5/5/03
to
Quoth W Isaac Carroll:
[...]

> * "do" is unclear
> * do-while in other languages doesn't have 2nd suite
> * do-while-while ambiguity
> * unseen "do" changes the meaning of seen "while"
>
> These are problems which I had not considered when writing the PEP.

Good! (Then the process is working.)

[...]


> * infinite loop with break is a well-known idiom in other languages and
> is a good way of expressing this behavior
>
> Experienced programmers are used to writing infinite loops and breaking
> out of them. However, saying "while True" does not clearly express the
> purpose and behavior of the loop. Just because it's traditional to write
> infinite loops does not mean that it's a good way to program.

Of course, with 'while True' and 'if ...: break', usually the loop
is not infinite (barring bugs). If I understand correctly, you're
saying that 'while True' suggests that the programmer *intends* an
infinite loop, and so is misleading.

If that's right, how about this?

loop:
do some stuff
if should stop now:
break
do some other stuff

The 'loop' just says "this is a loop; execution comes back here at
the end of the block". Unlike 'while True', it does not also
explicitly say "we will continue looping as long as True is true".
(The notion is that the problem is while's mandatory condition,
which adds no information in the case of these so-called infinite
loops.)

Any better in your view? (I can't tell; I'm too used to looking
for 'if ...: break' after seeing 'while True'.)

> I feel that the use of break is similar to the use of goto in the past.

> Goto was necessary because of the limited control structures available
> in early languages, but as for, while, if-else, functions, and other
> powerful control structures came into use, the goto was no longer
> necessary and gradually disappeared. If we adopt loop constructs of
> sufficient power and flexibility, the break statement will also no
> longer be needed, and will disappear from use.

Imho 'break' and 'continue' together make 'while' a "loop
construct of sufficient power and flexibility". :)

Incidentally, I'd like to see a concrete example of the kind of
problem which you'd solve by writing a loop with the proposed
syntax. (Most such cases in my experience are problems involving
a stream of objects to be processed; it would be nice to see
either a different kind of problem for which this syntax is
suited, or a stream-of-objects problem for which it is superior to
approaches using, say, iterators and a for loop.)

[...]
--
Steven Taschuk stas...@telusplanet.net
"[T]rue greatness is when your name is like ampere, watt, and fourier
-- when it's spelled with a lower case letter." -- R.W. Hamming

Gareth McCaughan

unread,
May 5, 2003, 4:12:50 PM5/5/03
to
Andrew Koenig wrote:

> This is obviously intended to be tongue-in-cheek. However, it does give
> me a thought about how to express this notion in a way that is much clearer
> and requires no new keywords:
>
> while:
> <setup code>
> and while <condition>:
> <loop body>

[etc]

This is very elegant. It's a pity that it doesn't work well
for the special case of a "do...while" loop, though.

--
Gareth McCaughan Gareth.M...@pobox.com
.sig under construc

Andrew Koenig

unread,
May 5, 2003, 5:36:38 PM5/5/03
to
>> while:
>> <setup code>
>> and while <condition>:
>> <loop body>

Gareth> This is very elegant. It's a pity that it doesn't work well
Gareth> for the special case of a "do...while" loop, though.

while:
<loop body>
and while <condition>:
pass

Gareth McCaughan

unread,
May 5, 2003, 6:58:04 PM5/5/03
to
Andrew Koenig wrote:
> >> while:
> >> <setup code>
> >> and while <condition>:
> >> <loop body>
>
> Gareth> This is very elegant. It's a pity that it doesn't work well
> Gareth> for the special case of a "do...while" loop, though.
>
> while:
> <loop body>
> and while <condition>:
> pass

Yes, of course. That's what I meant by "doesn't work well
with". I'm sorry if that wasn't clear.

Neil Hodgson

unread,
May 5, 2003, 7:23:34 PM5/5/03
to
Andrew Koenig:

> By implication, there is no obvious reason that one could not write
>
> while <condition1>:
> <code1>
> and while <condition2>:
> <code2>
> and while <condition3>:
> <code3>

> ...


>
> Looking at these examples, I find myself liking the "and while" idea more,
> because it uses (negative) indentation to mark the possible exit points.

Allowing break expressions to dedent would help clarify the current
idiom:

while <condition1>:
<code1>
break if <condition2>:
<code2>

Or to make the colon scan better:

while <condition1>:
<code1>
break if <condition2> else:
<code2>

Neil

Terry Reedy

unread,
May 5, 2003, 7:53:50 PM5/5/03
to

"rzed" <Dick....@lexisnexis.com> wrote in message news:b96fk8$u2>

I'd still prefer to see an indention of the entire while block,
> though -- it seems more obvious:
>
> while <condition1>:
> <code1>
> and if <condition2>:
> <code2>
> and if <condition3>:
> <code3>


As I understand the proposal, this is computationally equivalent to
and only marginally different in form from the currently legal

while <condition1>:
<code1>
if <condition2>:
<code2>
if <condition3>:
<code3>
else: break
else: break

So the proposals seem to be about changing indentation and making
break implicit instead of explicit. This is at most an esthetic and
not a functional enhancement.

I am currently thinking that Python's syntax should be 'congealed' --
not quite frozen but far from liquid -- and (with at most a few
exceptions) only changed (at least for 2.x series) for reasons other
than the syntax change itself. Examples are any remaining changes
needed to finish unify ints and longs or types and classes.

Terry J. Reedy


W Isaac Carroll

unread,
May 5, 2003, 7:01:24 PM5/5/03
to
Andrew Koenig wrote:
> while:
> <loop body>
> and while <condition>:
> pass

It was suggested to me that the colon might be left off for a statement
that does not begin a block, like so:

while:
<loop body>
and while <condition>

It remains to be seen whether the small difference of a missing colon is
enough to remind people that the block is not present.

TTFN


Evan Simpson

unread,
May 5, 2003, 7:11:55 PM5/5/03
to
Andrew Koenig wrote:
> Gareth> This is very elegant. It's a pity that it doesn't work well
> Gareth> for the special case of a "do...while" loop, though.
>
> while:
> <loop body>
> and while <condition>:
> pass

I'd be more inclined to go with:

while:
<loop body>
and while <condition>:

continue

...just for the way it sounds when read aloud.

Cheers,

Evan @ 4-am

Delaney, Timothy C (Timothy)

unread,
May 5, 2003, 7:34:28 PM5/5/03
to
> From: Andrew Koenig [mailto:a...@research.att.com]

>
> while <condition1>:
> <code1>
> and while <condition2>:
> <code2>
> and while <condition3>:
> <code3>

This would remove my objection to the fact that the condition is outdented, since it provides an obvious indication (and) that it's a continuation of an existing structure.

Hmm ... how does it look without outdenting?

while [<condition1>]:
<code1>
and while <condition2>:
<code2>
and while <condition3>:
<code3>

I think I prefer it with the outdents.

Tim Delaney

Andrew Koenig

unread,
May 5, 2003, 7:47:53 PM5/5/03
to
Tim> Hmm ... how does it look without outdenting?

Tim> while [<condition1>]:
Tim> <code1>
Tim> and while <condition2>:
Tim> <code2>
Tim> and while <condition3>:
Tim> <code3>

Tim> I think I prefer it with the outdents.

Me too.


Greg Ewing (using news.cis.dfn.de)

unread,
May 6, 2003, 12:08:10 AM5/6/03
to
W Isaac Carroll wrote:
> PEP: 315
>
> do:
> <setup code>
> while <condition>:
> <loop body>

I like the idea, but not the choice of keywords. I
would prefer to see

while:
<setup code>
gives <condition>:
<loop body>

--
Greg Ewing, Computer Science Dept,
University of Canterbury,
Christchurch, New Zealand
http://www.cosc.canterbury.ac.nz/~greg

Daniel Fackrell

unread,
May 6, 2003, 12:12:20 PM5/6/03
to
"Steven Taschuk" <stas...@telusplanet.net> wrote in message
news:mailman.105216643...@python.org...
> Quoth W Isaac Carroll:

> > I feel that the use of break is similar to the use of goto in the past.
> > Goto was necessary because of the limited control structures available
> > in early languages, but as for, while, if-else, functions, and other
> > powerful control structures came into use, the goto was no longer
> > necessary and gradually disappeared. If we adopt loop constructs of
> > sufficient power and flexibility, the break statement will also no
> > longer be needed, and will disappear from use.
>
> Imho 'break' and 'continue' together make 'while' a "loop
> construct of sufficient power and flexibility". :)


Out of curiousity, supposing that the "while and while ..." syntax were
accepted, are we going to start seeing requests for continue statements that
can continue at any while? It wouldn't terribly surprise me, and my gut
feel tell me that following that path would be a Bad Thing(tm).

Charles Hixson

unread,
May 6, 2003, 1:23:20 PM5/6/03
to
W Isaac Carroll wrote:
> PEP: 315
> Title: Enhanced While Loop
> Version: $Revision: 1.1 $
> Last-Modified: $Date: 2003/05/02 22:53:32 $
> Author: W Isaac Carroll <icar...@pobox.com>
> Status: Draft
> Type: Standards Track
> Content-Type: text/plain
> Created: 25-Apr-2003
> Python-Version: 2.4
> Post-History:
>
>
> Abstract
>
> This PEP proposes adding an optional "do" clause to the beginning
> of the while loop to make loop code clearer and reduce errors
> caused by code duplication.
...
Perhaps this should be done in a more general way. Just create a block
keyword, do: is fine.

what this keyword does is introduce a logical level of grouping (i.e.,
the code underneath it is indented once.) It is strictly equivalent to
"if True:"

Whether this would be worthwhile or not, I don't know, but it seems both
simple and sufficient to satisfy what I understand of your request.
I.e., it would allow one to write
do:
""" some code """
while(test):
""" some more code """

Unfortunately, I can think of many variations on this that would be
equally valuable, e.g., one that only executes once, or only executes
when a control variable == None, or one that locks access when another
thread is using it or...
And with so many similar plausibilities, probably none of them are
really appropriate (though that sync method has arguments, Java has
something like that).
--
-- Charles Hixson
Gnu software that is free,
The best is yet to be.

Andrew Koenig

unread,
May 6, 2003, 2:13:36 PM5/6/03
to
Daniel> Out of curiousity, supposing that the "while and while ..."
Daniel> syntax were accepted, are we going to start seeing requests
Daniel> for continue statements that can continue at any while? It
Daniel> wouldn't terribly surprise me, and my gut feel tell me that
Daniel> following that path would be a Bad Thing(tm).

Agreed. However, I can't imagine when such a control structure would
be useful. Perhaps I'm biased, because I almost never use continue
statements, but if I am, you should nave no difficulty finding
an example for us :-)

Erik Max Francis

unread,
May 6, 2003, 3:39:56 PM5/6/03
to
W Isaac Carroll wrote:

> PEP: 315
> Title: Enhanced While Loop
> Version: $Revision: 1.1 $
> Last-Modified: $Date: 2003/05/02 22:53:32 $
> Author: W Isaac Carroll <icar...@pobox.com>
> Status: Draft
> Type: Standards Track
> Content-Type: text/plain
> Created: 25-Apr-2003
> Python-Version: 2.4
> Post-History:
>
> Abstract
>
> This PEP proposes adding an optional "do" clause to the beginning
> of the while loop to make loop code clearer and reduce errors
> caused by code duplication.

Lukewarm. The while True: ... if condition: break ... is so widespread
and understandable that I don't see any huge benefit from the
introduction of a new construct for handling it, but at the same time
wouldn't be strongly opposed to one being added to the language.

The other variants which involve a

KEYWORD condition:
statements

where it's just "understood" that the statements will be executed once
regardless seems like a very bad precedent, since it's quite nonobvious
that that's the case, and I can't imagine a reasonable keyword used
there that would flag that behavior in an intuitive way.

--
Erik Max Francis / m...@alcyone.com / http://www.alcyone.com/max/
__ San Jose, CA, USA / 37 20 N 121 53 W / &tSftDotIotE
/ \ To be adult is to be alone.
\__/ Jean Rostand
CatCam / http://www.catcam.com/
What do your pets do all day while you're at work? Find out.

Erik Max Francis

unread,
May 6, 2003, 3:43:49 PM5/6/03
to
Steven Taschuk wrote:

> I have to agree with Alex here: Ick. My expectation on seeing
> until foo():
> bar()
> is that it would be equivalent to
> while not foo():
> bar()
> The proposed out-of-order execution is a recipe for confusion,
> imho.

Agreed. There is precedent for such an "until" construct (i.e., one
that simply a while with a negated conditional) in other languages, such
as Perl. So not only would such a construct be nonobvious, there is
directly conflict with what it would mean in other languages. Giving
false indicators of intuitiveness is a really, really bad idea.

(And no, I don't think a Perl-like "until" should be added, either.)

Gareth McCaughan

unread,
May 6, 2003, 2:58:20 PM5/6/03
to
Charles Hixson wrote:

> Perhaps this should be done in a more general way. Just create a block
> keyword, do: is fine.
>
> what this keyword does is introduce a logical level of grouping (i.e.,
> the code underneath it is indented once.) It is strictly equivalent to
> "if True:"
>
> Whether this would be worthwhile or not, I don't know, but it seems both
> simple and sufficient to satisfy what I understand of your request.
> I.e., it would allow one to write
> do:
> """ some code """
> while(test):
> """ some more code """

It would allow you to write that, but it wouldn't
mean what WIC wants it to. In his proposal, the
loop body contains both suites; in yours, it contains
only the second.

Daniel Fackrell

unread,
May 6, 2003, 6:24:55 PM5/6/03
to
"Erik Max Francis" <m...@alcyone.com> wrote in message
news:3EB80F8C...@alcyone.com...

> The other variants which involve a
>
> KEYWORD condition:
> statements
>
> where it's just "understood" that the statements will be executed once
> regardless seems like a very bad precedent, since it's quite nonobvious
> that that's the case, and I can't imagine a reasonable keyword used
> there that would flag that behavior in an intuitive way.

I think my biggest problem with the PEP and the modified versions which are
following it on this thread is that the whole idea addressed a very small
set of real-world use cases, and that it would likely set a bad precedent
which could allow a figurative avalanche of flow-control structures that are
begging to be added to the language.

Just to illustrate based on the idea presently before us, we have in the
language already:

while <cond>:
<statements>

This proposal would add some variation to allow setup code to be executed as
part of the loop, but before the <cond>, which is argued as a convenient way
of handling setup code (I've picked my favorite of the variations):

while <optionalCond>:
<statements>
and while <cond>:
<statements>

If we let this in, might we soon see a request to allow a portion of the
loop to execute once after the <cond> tests false for the purpose of
allowing some sort of cleanup to occur that might run a risk of duplicating
code?

And let's not neglect the fact that some other languages have negative logic
versions of their flow-control statements, so if pressure continued long
enough, we might (shudder) see new keywords added to eliminate the need for
a "not".

After typing this, I'm starting to feel that maybe this is just an
unimportant, meaningless tangent. I sure hope so.

Marcus Alanen

unread,
May 5, 2003, 5:43:34 PM5/5/03
to
On Mon, 5 May 2003 15:54:58 -0400, rzed <Dick....@lexisnexis.com> wrote:
>Andrew says that this:
>
>> while <condition1>:
>> <code1>
>> and while <condition2>:
>> <code2>
>> and while <condition3>:
>> <code3>
>
>would be equivalent to this:
>
>>
>> while <condition1>:
>> <code1>
>> if not (<condition2>): break
>> <code2>
>> if not (<condition3>): break
>> <code3>
>>
>... which means that the first 'while' and the second do not mean the
>same thing. That's less than "obvious" (ergo, less than "Pythonic"?).
>If "while" does not imply a looping construct, why use the word?

while <condition1>:
<code1>
break unless <condition2>
<code2>
break unless <condition3>
<code3>

Too Perlish?-) But it does read rather good, in my humble opinion.
Even "break if not <condition>" could be a small readability improvement,
the eye ought to see the "break" word easier. Since list comprehensions
have an optional if part, why can't break?

>I'd still prefer to see an indention of the entire while block,
>though -- it seems more obvious:
>
>while <condition1>:
> <code1>
> and if <condition2>:
> <code2>
> and if <condition3>:
> <code3>

Not that much difference between it and the standard
"if not condition2: break" code.

Marcus

SUZUKI Hisao

unread,
May 7, 2003, 5:32:34 AM5/7/03
to
In <mailman.105216643...@python.org>, Steven Taschuk wrote:
[...]

> Of course, with 'while True' and 'if ...: break', usually the loop
> is not infinite (barring bugs). If I understand correctly, you're
> saying that 'while True' suggests that the programmer *intends* an
> infinite loop, and so is misleading.
>
> If that's right, how about this?
>
> loop:
> do some stuff
> if should stop now:
> break
> do some other stuff
>
> The 'loop' just says "this is a loop; execution comes back here at
> the end of the block". Unlike 'while True', it does not also
> explicitly say "we will continue looping as long as True is true".
> (The notion is that the problem is while's mandatory condition,
> which adds no information in the case of these so-called infinite
> loops.)
>
> Any better in your view? (I can't tell; I'm too used to looking
> for 'if ...: break' after seeing 'while True'.)
[...]

> Imho 'break' and 'continue' together make 'while' a "loop
> construct of sufficient power and flexibility". :)

I think so, too.
I wish Python kept clean without overdone constructs... I think it
is better only to add an intuitive keyword "loop" which is equivalent
to "while True" (like several other languages) if we need to fix the
language.

And from the mathematical view, "while...else..." is cleanly
defined. Let W be "while e: s else: t".
Then W is the least fixed point of the equation:
W = if e:
s; W
else:
t

Imho, both constructs of W. I. Carroll and A. Koenig lack
such simplicity.

-- SUZUKI Hisao


Andrew Koenig

unread,
May 7, 2003, 7:44:11 AM5/7/03
to
Marcus> while <condition1>:
Marcus> <code1>
Marcus> break unless <condition2>
Marcus> <code2>
Marcus> break unless <condition3>
Marcus> <code3>

Marcus> Too Perlish?-) But it does read rather good, in my humble opinion.

I think I disagree. The point is that the multiple exits should be
considered normal exits, not abnormal ones. The difference appears
when you add an "else" clause:

while:
line = infile.getline()
and while line:
<process the line>
if <something is wrong>: break
else:
<code to execute after normal exit>

If the loop terminates normally -- that is, because we reached the end
of the file -- I would like the code after "else:" to execute. If,
on the other hand, it terminates because of the break, I would like the
code after "else:" not to execute.

I think this behavior is analogous to the current usage:

for line in infile:
<process the line>
if <something is wrong>: break
else:
<code to execute after normal exit>

I'm sure someone will correct me if I'm wrong :-)

Gareth McCaughan

unread,
May 7, 2003, 6:25:56 PM5/7/03
to
SUZUKI Hisao wrote:

> And from the mathematical view, "while...else..." is cleanly
> defined. Let W be "while e: s else: t".
> Then W is the least fixed point of the equation:
> W = if e:
> s; W
> else:
> t
>
> Imho, both constructs of W. I. Carroll and A. Koenig lack
> such simplicity.

while C1:
S1
and while C2:
S2
else:
E

is the least fixed point of

W1 == if C1: { S1; W2 }
else: E
W2 == if C2: { S2; W1 }
else: E

But I'm not sure why this is important, since (1) neither
of these deals with "break" and "continue" and (2) maybe
0.001% of Python programmers think of their programs as
built out of least fixed points of sets of equations.

Tim Peters

unread,
May 7, 2003, 10:06:52 PM5/7/03
to
[Gareth McCaughan]
> ...

> (2) maybe 0.001% of Python programmers think of their programs as
> built out of least fixed points of sets of equations.

It's actually about 43%. However, in the spirit of newbie-friendly
egalitarianism, most of them aren't gauche enough to mention it.

you-can't-spell-python-without-the-y-combinator-ly y'rs - tim


Beni Cherniavsky

unread,
May 11, 2003, 8:12:06 AM5/11/03
to
Michael Chermside wrote on 2003-05-05:

> > [W Isaac Carroll posted PEP 315 (revision 1.1)]
>
> Isaac:
>
> Thanks for the excellently written PEP! There are three minor
> changes that I would propose. First, incorporate Alex's
> suggestion of "loop" instead of "do" for the introductory
> keyword:
>
> loop:
> <loop code>
> while condition:
> <more loop code>
>
I agree that ``loop:`` is better than ``while 1:`` and ``while True:``
(I must admit that while I like `True`/`False`, I still prefer the
``1`` since a number visually stands out better and it looks more
"syntetic"). However I'd perhaps prefer ``while:`` over ``loop:`` for
the ``and while`` proposals. Make clear that this part of the PEP is
optional.

> which is (IMHO) quite readable. Secondly, I would suggest
> re-ordering the motivation section to stress the particular
> existing-syntax-alternative which is most strongly supported
> by python experts and PEP opponents. They tend to prefer the
> synatx of:
>
> while True:
> <loop code>
> if not condition: break
> <more loop code>
>
> so I would list that alternative first, or perhaps just
> indicate in the discussion that it's the syntax preferred by
> many in the absense of the PEP. Of course, you should KEEP
> the comments about why this solution is not desirable...
> after all, this is the MOTIVATION section!
>
Agreed. Moreover, you should call the construct by its known name -
"loop-and-a-half". AFAIK, this construct was first published in
Knuth's excellent "Structural programming with GOTO" paper (google for
it) and there he invented this name.

> Thirdly, I would suggest that you clearly address the problem
> of "dangling while" and specify how it is to be addressed.

This is fixed in the ``and while`` idea. I'd like to suggest a few
variants. First, the "ideal" indentation would be::

loop:
<suite>
<cond>:
<suite>

This is very alien to python's indentation style so it'd not work.

Somebody said ``and while`` sounds wrong because it seems to split it
into several loops, suggesting ``and if``. I'd like to propose a bare
``and``::

while:
<suite>
and <cond>:
<suite>

This reads stangely if the first while has no condition, so perhaps
even the ``and`` should be omitted (*Parsing danger*, Will Robinson).
As a radical option, consider this::

while
<suite>
<cond>:
<suite>

This reads nicely as "a while whose condition was moved into the
middle of the loop :-). Yes, I know Guido will not accept this.

> Lastly, I would suggest that you _define_ the behavior of
> the new construct in terms of existing syntax. Guido likes
> that...

Basically good idea.

>[snip]
> but you'll have to be very careful about handling all
> situations including "else" clauses... so I'd probably
> add that:
>
> The behavior when an "else" clause is present:
> [snip]
> will be exactly the same as the behavior of
>
> >>> __normal_loop_exit__ = False
> >>> while True:
> ... <suite 1>
> ... if not <condition>:
> ... __normal_loop_exit = True
> ... break
> ... <suite 2>
> >>> if __normal_loop_exit__:
> ... <suite 3>
> >>> del __normal_loop_exit__
>
> *except* for the fact that the variable
> "__normal_loop_exit__" will not be visible in any
> scope.
>
If *that's* how you'll define it, I think it's a bad idea. At this
stage, IMHO it's best to just give the whole new definition of
``while``.

> Anyway, nice work on this PEP... it's something we've needed
> for a long time.
>
Seconded.

> Now for the bad news. I'm -1 on this PEP. I think it should
> be rejected, for two reasons: I think the alternative *IS*
> sufficiently readable (reasonable people could disagree, but
> that's my opinion) and I find newbies tend to write better
> code (fewer errors) if they are forced to do their tests at
> the top of the loop (which is where the tests belong for the
> overwelming majority of loops).
>
> But enough of *MY* reasons... this is a FREQUENT request, and
> it deserves a good writeup and evenhanded consideration. If
> it's accepted, we'll have a new language feature (and it should
> be as well-designed as possible). If it is rejected, at least
> what got considered was the very BEST syntax possible.
>
There is a trivial test that nobody seems to have done yet:

$ cd Python-2.3b1/Lib
$ find -name '*.py' | xargs cat | grep -c $'^[ \t]*while .*:'
730
$ find -name '*.py' | xargs cat | grep -c $'^[ \t]*while 1:'
220
$ find -name '*.py' | xargs cat | grep -c $'^[ \t]*while True:'
50

WOW! That means that about *every third* while loop in the standard
library is an "infinite" loop! I'm sure each of them has a break. I
can't easily check how many have simple post-conditions ("do until")
but in my experience, checking at the end is less useful than at the
middle. These statistics convince me that this PEP is definitely not
YAGNI.

The other notable thing is that there are only ~730 while loops in the
whole standard library (a little more, the ``.*:`` misses multi-line
conditions). The simple truth is that ``for`` is just much more
useful:

$ find -name '*.py' | xargs cat | grep -c $'^[ \t]*for .* in .*:'
2683

As expected ;-)

--
Beni Cherniavsky <cb...@users.sf.net>

"Intercept course punched in." -- from a sci-fi movie, happening
centuries from now. So don't forget your puch-card skills yet!

SUZUKI Hisao

unread,
May 13, 2003, 4:36:31 AM5/13/03
to
In <slrnbbj1vk.21k2....@g.local>, Gareth McCaughan wrote:
>
>> And from the mathematical view, "while...else..." is cleanly
>> defined. Let W be "while e: s else: t".
>> Then W is the least fixed point of the equation:
>> W = if e:
>> s; W
>> else:
>> t
>>
>> Imho, both constructs of W. I. Carroll and A. Koenig lack
>> such simplicity.
>
> while C1:
> S1
> and while C2:
> S2
> else:
> E
>
> is the least fixed point of
>
> W1 == if C1: { S1; W2 }
> else: E
> W2 == if C2: { S2; W1 }
> else: E

Thus,

W1 == if C1:
S1

if C2:
S2
W1
else:
E
else:
E

> But I'm not sure why this is important, since (1) neither

> of these deals with "break" and "continue" and (2) maybe


> 0.001% of Python programmers think of their programs as
> built out of least fixed points of sets of equations.

Yes, many ones do not think of fixed points, but I hope you
will understand the core point easily. Well, you can see the
equation just a "macro" definition ;-). Frankly speaking,
"least" just means that the interpreter executes only what
written in the given program.

The important point is that you can see the (non-)simplicity
of the given construct from its equation (read 'macro') clearly.

Given the equation, you can now see the secret of the "else"
clause of "while" statement of Python, which seems very
unique :-) It corresponds that of "if" plainly. I believe
the naturalness of the "while..else.." comes from this.

"and while" lacks such simple correspondence and has
multiple occurrences of E (statements in "else" clause).

And you may think of a looping construct which is described
as a recursive "if..elif..". For example,

while C1:
S1
or while C2:
S2
or while C3:
S3
else:
E

whose meaning is given by

W = if C1:
S1; W
elif C2:
S2; W
elif C3:
S3; W
else:
E

Note that it is not my invention. If I remember correctly,
Concurrent Pascal had such a construct.
Though I doubt its actual usefulness, it is so natural
that some may mistake the meaning of "and while" for it ;-)

Thus I want a plain "loop", if we have to fix the looping
constructs of Python.

BTW, as for "break" and "continue", I think there are two
approaches.
A: unfold the equation, and reduce it to "if..else..".
B: use "try..raise..except.." construct.
If I remember correctly, the Modula-3 report takes the
approach B to describe its BREAK statement.

-- SUZUKI Hisao


0 new messages