PEP 315: Enhanced While Loop

Francis Avila francisgavila at yahoo.com
Sun May 4 13:26:08 EDT 2003


"Steven Taschuk" <staschuk at telusplanet.net> wrote in message
news:mailman.1051981266.22767.python-list at 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





More information about the Python-list mailing list