Conditional Expressions don't solve the problem

Kevin D salemail at dial.pipex.com
Wed Oct 17 12:24:11 CEST 2001


Guido van Rossum <guido at python.org> wrote in message news:<cpn12riiqr.fsf at cj20424-a.reston1.va.home.com>...
> On the other hand, the ability to hide an assignment inside an
> expression is IMO purely a way to save some keystrokes: the variable
> needs to be named anyway, so you may as well do the assignment in a
> separate step so that the reader is alerted of it.

But "hiding an assignment inside an expression" is just the proposed
solution (based on the C idiom) to an identified problem. As an
alternative to considering whether the C functionality should be
adopted (and personally, I'm happy if it isn't) I think we should go
back and think up a Pythonic solution to the original problem (the
while loop thing, IIRC).

As I see it, there are two basic ways to write a while loop with a
'load' stage, each with it's own problems:

1) Duplication of the 'load':

foo = some_long_expression
while foo != terminating_condition:
    body_of_loop()
    foo = some_long_expression

The argument for only having to spell the 'load' of "foo" once is the
same as part of the argument for augmented assignment (mis-spelling of
the expression leading to subtle bugs). This is more acute than for
augmented assignment, as the load inside the body of the loop could be
a great physical distance on the screen from the initial load it is
duplicating.

2) "while 1" idiom:

while 1:
    foo = some_long_expression
    if foo == terminating_condition:
        break
    body_of_loop()

This solves problem (1) but IMHO, falls down in your "interrupting the
thought process" requirement - it takes some mental juggling to work
out just what the condition _is_ when reading the code. This is partly
because the actual termination condition is buried somewhere away from
the "while" statement and partly because the condition is reversed (so
having searched out the termination condition, you must then read it
as "until <condition>", or "while not <condition>" - either way, the
code has to be mentally "translated"/restructured as it's being read).

So, to fix those problems a solution must:

1) Allow the loop's "load" code to exist just once, preferably
somewhere near the terminating condition.
2) Have the terminating condition near the "while", and of the right
"polarity".
3) To be Pythonic, have an obvious meaning.

As an opening gambit, what about something like:

while <condition>; <keyword> <assignment-statement>:
    <body>

Something like:

while foo != terminating_condition; given foo = some_long_expression:
    body_of_loop()

or maybe "where":

while foo != terminating_condition; where foo = some_long_expression:
    body_of_loop()

This would extend to 'if'/'elif':

if m is not None; where m = compiled_re.match(inputline):
    stuff(m)
elif m is not None; where m = compiled_re2.match(inputline):
    otherstuff(m)

I'm not sure if the semi-colon would be neccessary/desirable.
Unfortunately, I think the extra keyword _is_ neccessary - it helps
make it read as English and therefore helps in the 'obvious meaning'
stakes.

Regards, Kev.



More information about the Python-list mailing list