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

P

Paul Rubin

Andrew Koenig said:
I think that reserving "break" for abnormal situations makes
programs easier to understand.

Nah, abnormal conditions are what "raise" is for.
Therefore, I would like a way of saying that I expect the normal
exit (or exits) from the loop to be in the middle. Whether you
consider this desire to be part of the real world is up to you.

But just looking at those code samples, they're either harder to
understand than using break, or else easily replaced by some other
construct. Is there a middle ground? Maybe, but I haven't seen a
concrete example yet.
 
G

Gerrit

I disagree. I think it's counter-intuitive to have an assignment inside
an expression. Assignments should be statements. Explicit is better than
implicit. What problem would this solve? And why the ':'?

Gerrit.
 
P

Paul Rubin

Gerrit said:
I disagree. I think it's counter-intuitive to have an assignment inside
an expression. Assignments should be statements. Explicit is better than
implicit.

There's nothing implicit about an assignment expression.
What problem would this solve? And why the ':'?

It solves the problem illustrated in that particular example of the
proposed new loop construction. The := is because one of the commonly
heard objections to assigmnent expressions is that people occasionally
type "if (x = y) ..." when they meant "if (x == y)", so there's a fear
that introducing assignment expressions with just "=" will cause a lot
of program bugs. With the colon, "if (x = y) ..." is still a syntax error.
 
J

Jeff Epler

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

I've certainly run into this using urllib2.

Push the "yucky" while 1: loop into a generator function,
and then use a regular "for" loop in the multiple places
you need to handle a file in this way:

def chunks(f, blocksize=512):
while 1:
b = f.read(blocksize)
if not b: return
yield b

Use it like this:....
'Fedo' 'ra C' 'ore ' 'rele' 'ase ' '1 (Y' 'arro' 'w)\n'

The "while 1:" loop is now so short that a simple glance can take it all
in, and the site with the logic uses the much clearer 'for' loop.

Jeff
 
P

Paul Rubin

Jeff Epler said:
Push the "yucky" while 1: loop into a generator function, ....

The "while 1:" loop is now so short that a simple glance can take it all
in, and the site with the logic uses the much clearer 'for' loop.

Yeah, except now you've bloated up your code with another function.
Assignment expression solves this one too.
 
J

Josiah Carlson

Huh? It's an expression, the value is explicit.

Perhaps no one has noticed that C's allowing of assignments in while/for
/if statements has caused more than one bug. Hell, there was a
much-publicised hole in the Linux kernel that was caused by this not 6
months ago.

Sure, there is a difference between '==' becoming '=', and '==' becoming
':=', but the difference is 1 inch and a shift key on my keyboard. I've
made larger errors when typing than just an inch and a shift-key. I
believe it would cause more bugs, reduce readability, and attempts to
fix a problem that doesn't really exist.

- Josiah
 
P

Paul Rubin

Josiah Carlson said:
Sure, there is a difference between '==' becoming '=', and '=='
becoming ':=', but the difference is 1 inch and a shift key on my
keyboard.

Oh come on, you're grasping at straws. What about the difference
between '>' and '<'? Those are even closer together than ':' and '='.
Do you want to get rid of those operations too? The '=' vs '==' thing
may actually confuse some people but it's hard to mistake := for
anything other than an assignment.
I've made larger errors when typing than just an inch and a
shift-key. I believe it would cause more bugs, reduce readability,
and attempts to fix a problem that doesn't really exist.

That's sheer speculation on your part. You've cited the existence of
assignment expression errors causing 'more than one bug' in the
hundreds of millions of C code written over the past three decades.
That's not persuasive of anything, given how many other bugs there are
of just about every other sort. And in fact, the one in the Linux
kernel shows the opposite of what you're claiming. It wasn't an
accidental error that slipped through anything; it was a deliberate
hole that someone introduced hoping no one would notice, but it was
noticed immediately, showing that the =/== distinction is less
difficult to spot than you seem to think.

Assignment expressions have been used successfully in C and other
languages for many years, including plenty of them in the CPython
code. It's reasonable to say they're used all the time by some very
capable programmers and it's impertinent of you to imply that those
programmers don't know what they're doing. If you don't like them,
fine, don't use them, but don't try to convince people who use them
that they're wrong. What's a programming language like Python aiming
to do, anyway? Among other things, it aims to make programming
non-frustrating. So if a sizeable population of users find that the
absence of a particular useful feature is actually frustrating, give
some thought to the idea that the absence really is a shortcoming in
the language.
 
J

Joe Mason

Huh? It's an expression, the value is explicit.

x = 1 (or x := 1) looks to me like a statement that sets x to 1, not an
expression. I wouldn't expect any return value, if my mind hadn't been
corrupted by C. So the fact that there's a return value at all is
implicit.

Joe
 
P

Paul Rubin

Joe Mason said:
x = 1 (or x := 1) looks to me like a statement that sets x to 1, not an
expression. I wouldn't expect any return value, if my mind hadn't been
corrupted by C. So the fact that there's a return value at all is
implicit.

What do you mean by "return value"? Only functoins have return
values. It's just a value, not a return value.
 
E

Erik Max Francis

Paul said:
What do you mean by "return value"? Only functoins have return
values. It's just a value, not a return value.

You know very well what he means, you're just being difficult at this
point.

What you're suggesting has been proposed, time and time again. And it
has been shot down, time and time again.
 
S

Stefan Axelsson

Yeah, except now you've bloated up your code with another function.
Assignment expression solves this one too.

Except that the 'bloat' is constant, you only need one function, once
to solve all your 'read'-problems. And hence that function probably
belongs in a library, like it does for 'readline', I have no doubt
that it'll end up there if this situation turns out to be a problem.

Generators/iterators gives you e.g. the opportunity to write:

by Dave K said:
from sets import Set
file('pruned_ips.txt', 'w').writelines(
Set(file('ips.txt')) - Set(file('excluded_ips.txt')))

This code relies on `writelines' accepting an iterable, sets returning
their members whenever iterated, Set constructors accepting an iterable,
and files returning their lines whenever iterated. And of course, on
`close' rarely being needed in Python! :)

Something that the assignment as expression doesn't.

I'd say the syntax is just right as it is. No extra complexity in
while loops or assignments as expressions is needed. In fact the
relative awkwardness of the present state serves as an excellent
opportunity to introduce generators/iterators.

Stefan,
 
P

Paul Rubin

Erik Max Francis said:
You know very well what he means, you're just being difficult at this
point.

No, I think he's preoccupied with distinctions that aren't there.
He said
x = 1 (or x := 1) looks to me like a statement that sets x to 1, not
an expression. I wouldn't expect any return value, if my mind hadn't
been corrupted by C.

but of course from my Lisper's point of view, the whole idea that a
statement and an expression are fundamentally different things is
itself a sign of a corrupted mind. I'm not willing to accept the
notion that the way C does it is the one that's "corrupt". C was
phenomenally successful despite its warts, because it was conducive to
an easy, fluid coding style, just like Python sometimes aspires to.
Assignment expressions were an aspect of that conduciveness. Python
itself has this really odd mixture of wonderful fluidity (I love list
comprehensions), and completely unnecessary, almost Calvinistic
moralizing over semi-trivial issues like assignment expressions, while
still leaving plenty of naked razor blades (unchecked exceptions, the
crazy scoping system, lack of protection on class attributes, etc.)
for the programmer to slash himself with.
What you're suggesting has been proposed, time and time again. And it
has been shot down, time and time again.

I'm unmoved by that observation. We've seen it plenty of times
before, that the need for something in Python was recognized for a
long long time, but shot down repeatedly before finally being fixed
(look at 'a += b'). Maybe this will be the same.
 
J

Joe Mason

No, I think he's preoccupied with distinctions that aren't there.
He said


but of course from my Lisper's point of view, the whole idea that a
statement and an expression are fundamentally different things is
itself a sign of a corrupted mind. I'm not willing to accept the

Aha! Now I see. Python is not Lisp. It has tons of imperative
constructs that don't return values. While loops, for instance.

Corrupt or not, though, the Lisp way is "everything implicitly returns a
value". I'm not arguing for or against assignment expressions - I think
it's pretty trivial. I'm just saying you can't claim they aren't
implicit. And the Zen of Python has things to say about that.

As a Lisper, shouldn't you be avoiding assignments because of their
side effects anyway? Surely you should be pushing for "let" bindings.

Speaking of which, even though I'm not particularly interested in new
syntax - break was fine for granpappy, and it's good enough for me -
let wouldn't be a bad keyword for the initialization section of the
loop. Except that wouldn't mean exactly what it does in function
languages, which would be confusing. "with" is another possibility -
the two uses I know are Pascal, where it just makes a record alias, and
Modula-3, where it works differently but I forget how. But it's already
overloaded, anyway.

Joe
 
R

Robin Munn

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

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

This example actually incorporates two changes:

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

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

I'm -1 on this idea, because "and while" just does not feel Pythonic to
me. I read the code above and see a loop that does "x = foo()" forever,
then when that loop is finished (whenever that may happen) proceeds to
do bar(x) as long as x != 0. In other words, the syntax is very
counter-intuitive to me, and causes me to do a couple of double-takes
before I figure it out.

I've sometimes wished for a construct like do ... while, but I would
rather live without one than have one that's counter-intuitive.
 
P

Paul Rubin

Joe Mason said:
Aha! Now I see. Python is not Lisp. It has tons of imperative
constructs that don't return values. While loops, for instance.

That's merely a side effect of the parser not giving you a way to
capture the value of a while loop. In Lisp, while loops return a
value. In Python, the value is, heh, "implicitly" discarded.
Corrupt or not, though, the Lisp way is "everything implicitly returns a
value". I'm not arguing for or against assignment expressions - I think
it's pretty trivial. I'm just saying you can't claim they aren't
implicit. And the Zen of Python has things to say about that.

Is the value of "2+2" also not implicit by the same logic? You're
using the word implicit in a pretty strange way, I think.
As a Lisper, shouldn't you be avoiding assignments because of their
side effects anyway? Surely you should be pushing for "let" bindings.

Never heard of setq? ;-)
Speaking of which, even though I'm not particularly interested in
new syntax - break was fine for granpappy, and it's good enough for
me - let wouldn't be a bad keyword for the initialization section of
the loop.

I find the proposed new loop syntax very confusing. I do see some
benefit for fixing up the initialization issue but think it should be
done at the top of the loop, not spread all through it. C's 'for'
loop is better, because it puts that stuff at the top.
 
V

Ville Vainio

Andrew> Any loop that is currently written in the form

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

Why not just make a new keyword, 'loop', an alias of "while 1"?

Usually it seems that the 'get data to process' is done immediately
after "while 1", and the break immediately after that. It's a good
construct, easy to understand and easy to type (if you use 'while 1'
instead of 'while True', that is - 'while True' seems like a rather
pointless excercise to me).

Also, the proposed construct doesn't IMVHO seem less cryptic at all -
exactly the opposite, in fact.
 
J

Josiah Carlson

Sure, there is a difference between '==' becoming '=', and '=='
Oh come on, you're grasping at straws. What about the difference
between '>' and '<'? Those are even closer together than ':' and '='.
Do you want to get rid of those operations too? The '=' vs '==' thing
may actually confuse some people but it's hard to mistake := for
anything other than an assignment.

Who said anything about confusing them? I merely stated that it would
be relatively easy to mistype. If what you are proposing is used, and
people actually try converting their old-style-while to new-style-while,
it would be easy to forget to insert the colon. When writing new loops,
it would also be relatively easy to slip and insert a := when intending
==. Looking at my keyboard, := rather than >= would be even more likely
(or even the reverse), because one already has the shift-key down, and
the keys are adjacent to one another.

You can say that I am grasping at straws, but ignoring mistyping as a
source for bugs, is foolish on your part.

That's sheer speculation on your part. You've cited the existence of
assignment expression errors causing 'more than one bug' in the
hundreds of millions of C code written over the past three decades.

I didn't offer more because I've never used the syntax in my C/C++ code,
nor have I waded through millions of lines of C. I also wouldn't want
to go through the potentially thousands of lines where it is used. That
would be a waste of time.

That's not persuasive of anything, given how many other bugs there are
of just about every other sort.

A better statement would have been, "That says nothing about the
proportion of bugs in such assignments, as compared with other
syntactical bugs." Which would be correct. But as I just said, I
haven't waded through millions of lines of C and categorized the types
of syntax bugs. Certainly it is speculation on my part, but it is
conservative speculation.

All proposed methods that ask to change syntax, deviates from Python
style, which /may/ introduce more bugs.

And in fact, the one in the Linux
kernel shows the opposite of what you're claiming. It wasn't an
accidental error that slipped through anything; it was a deliberate
hole that someone introduced hoping no one would notice, but it was
noticed immediately, showing that the =/== distinction is less
difficult to spot than you seem to think.

I never claimed it was difficult to spot. I claimed it was easy to make
such a typing mistake. Certainly the exploit was deliberate, but had
the linux kernel not been as well audited as it is, the bug may have
persisted. In the few thousand lines of C code I wrote during
undergrad, I know I made a handful of == -> = typing errors. I expect
that the occasional slip from one to the other is not uncommon.

Assignment expressions have been used successfully in C and other
languages for many years, including plenty of them in the CPython
code. It's reasonable to say they're used all the time by some very
capable programmers and it's impertinent of you to imply that those
programmers don't know what they're doing.

You seem to like to put words into people's mouths. I never said that C
programmers don't know what they are doing when they are using them. I
said that it would be easy to mistype, and seeks to solve a "problem" in
Python that isn't one.

If you don't like them,
fine, don't use them, but don't try to convince people who use them
that they're wrong.

What people do with other langauges, I do not concern myself with. If
you want to use while (a = b) in other languages, feel free. On the
other hand, when you talk about taking a language that I care about,
that I use on a daily basis for both work and play, and mangle it with
what I consider to be useless syntax, I (and everyone else I expect)
reserve the right to give my opinion. I never said that its use in
other languages was wrong, just that I don't want it in Python. Which
leads me to:

I think PEP 315 is a waste of bits. In my opinion, Python doesn't need
a syntax change for while loops, and those who cannot understand the
flow of:

while 1:
#setup
if <condition to stop>: break
#loop internals

Are operating on a lower conceptual level than the majority of CS
undergrads that I teach on a daily basis at UC Irvine. Now, UCI is a
decent school, so maybe we are setting the bar too high. However, the
above while loop is clearer (even though it is more verbose), than all
of the suggested syntax changes.

What's a programming language like Python aiming
to do, anyway? Among other things, it aims to make programming
non-frustrating. So if a sizeable population of users find that the
absence of a particular useful feature is actually frustrating, give
some thought to the idea that the absence really is a shortcoming in
the language.

I did give some thought to it. I think the bugs that may occur as a
result of its availability would be far more frustrating than the
relatively minor additional typing required for old-style loops.

- Josiah
 
D

Dave K

On 19 Feb 2004 09:29:08 GMT in comp.lang.python, Stefan Axelsson

(snip)
Generators/iterators gives you e.g. the opportunity to write:

Just for the record, that was actually written by François Pinard, not
me. Well worth quoting again, though, as it's a lovely example.
Something that the assignment as expression doesn't.

I'd say the syntax is just right as it is. No extra complexity in
while loops or assignments as expressions is needed. In fact the
relative awkwardness of the present state serves as an excellent
opportunity to introduce generators/iterators.

FWIW, I think I agree with you. I'm no expert on generators, but I do
know one thing - they're *much* more powerful and flexible than I
currently realise :)

Dave
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,046
Latest member
Gavizuho

Latest Threads

Top