"and while" Patch for Python 1.5.2
Version 0.10: 18th May, 1999

Overview
--------

This patch to the source of Python extends the 'while' statement to
allow the following sort of construction:

while:
    suite
and while test:
    suite

'else' statements are still permitted as an option.  This will loop
through both suits, but will exit the loop at the 'and while'
statement if the test fails.


Purpose
-------

This is intended as a more flexible and faster substitute for the
traditional construction:

while 1:
    suite
    if not test:
        break
    suite

It is slightly different in that the loop exit at an 'and while' is
considered normal loop termination, and it will execute any 'else'
suite that may be present.

It also has the advantage that the bytecode generated is more
efficient than the 'while 1: ... break' construction because it
eliminates the redundant test of 1 in every loop, and flow through
the loop has less jumps.

Finally, it satisfies some of the calls for C-like assignment in
expression in a very natural way for Python.  Idiomatic C while loops:

i = 0
while (i++ < n) {
    ...
}

can be written:

i = 0
while:
    i = i+1
and while i < n:
    ...

Also, "do ... while test" constructions can be written as:

while:
    ...
and while test: pass


Details
-------

After the patch, the grammar of the while statement is modified to
read:

while [':' suite 'and' 'while'] test ':' suite ['else' ':' suite ]

The patch modifies comp_while_stmt in compile.c to compile this into
bytecode - all that is needed to achieve this is the optional
insertion of the first suite before the test.

The patch also patches graminit.c to reflect the new grammar, although
you could generate this from the new Grammar file using pgen.

No presently working code should be broken by this patch.


Discussion
----------

This variant of the while loop was suggested on comp.lang.python by
(who?).  I would find it more natural to write this as 'do: ... while
test: ...', however this present construction has the advantage of
being backwardly compatible with existing Python code and does not
introduce any new keywords.

There were some suggestions of allowing constructs like:

while test:
    ...
and while test:
    ...
and while test:
    ...
else:
    ...

and something like this would be easy to write - the problem being
that it is not clear to me how this should behave.  Should each 'and
while' jump to the 'else' on failure, exiting the loop?  Or should it
behave more like:

while 1:
    ...
    if test:
        ...
        continue
    elif test:
        ...
        continue
    else:
        break
else:
    ...

There are probably places where both would be useful to have, but
neither seems naturally 'right' to me.  So because of the potential
confusion, this patch only allows one test in the loop.


Corran Webster
cwebster@nevada.edu

