440,928 Members | 1,173 Online
Need help? Post your question and get tips & solutions from a community of 440,928 IT Pros & Developers. It's quick & easy.

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

 P: n/a PEP 315 suggests that a statement such as do: x = foo() while x != 0: bar(x) be equivalent to while True: x = foo() if x == 0: break bar(x) I like the overall idea, but wonder about the extra keyword. Moreover, if you see x = foo() while x != 0: bar(x) you have to read backward to see whether the assignment to x is part of this statement or part of a previous statement. 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 :" is an exit from the middle of the loop, analogously to PEP 315. My proposal allows for multiple exits in the obvious way while : and while : and while : ... in which all of the conditions and statements are evaluated in the order shown until a condition is false, at which point the loop terminates. It also occurs to me that this notion can be generalized to include "or while" as well as "and while". Using "or while" would implement a control structure that Dijkstra proposed in "A Discipline of Programming". The idea would be that while : or while : or while : would be equivalent to while True: if : elif : elif : : else: break This notion is still partly baked, if for no other reason than that I'm not sure how a statement with both "or while" and "and while" clauses should work. My first thought is for "and while" to have priority over "or while", analogously with expressions, but then the following example came to me. It's the inner loop of a binary search: while low < hi: mid = (low + hi) // 2; and while value < table[mid]: high = mid or while value > table[mid] low = mid If "and" has higher precedence than "or", this example doesn't work. So I'm not sure about its merits -- but I'm mentioning it in case someone else can improve on it. Jul 18 '05 #1
24 Replies

 P: n/a "Andrew Koenig" writes: PEP 315 suggests that a statement such as do: x = foo() while x != 0: bar(x) I'm still scratching my head over that PEP. Got a real-world code sample that it would improve? Jul 18 '05 #2

 P: n/a Paul Rubin wrote: I'm still scratching my head over that PEP. Got a real-world code sample that it would improve? do: line = inputFile.readline() while line: ... line = inputFile.readline() -- __ Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/ / \ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE \__/ The doors of Heaven and Hell are adjacent and identical. -- Nikos Kazantzakis Jul 18 '05 #3

 P: n/a Erik Max Francis wrote: Paul Rubin wrote: I'm still scratching my head over that PEP. Got a real-world code sample that it would improve? do: line = inputFile.readline() while line: ... line = inputFile.readline() Man, what a perfect gaffe on my part. The purpose of the do...while construct is to _eliminate_ the duplication. This should be: do: line = inputFile.readline() while line: ... -- __ Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/ / \ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE \__/ The doors of Heaven and Hell are adjacent and identical. -- Nikos Kazantzakis Jul 18 '05 #4

 P: n/a Erik Max Francis writes: do: line = inputFile.readline() while line: ... line = inputFile.readline() So it's yet another workaround for Python's lack of assignment expressions. I like while (line := inputFile.readline()): ... a lot better. Jul 18 '05 #5

 P: n/a Paul Rubin wrote: So it's yet another workaround for Python's lack of assignment expressions. I like while (line := inputFile.readline()): ... a lot better. (Please check my correction, it's actually not as dumb as I suggested.) -- __ Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/ / \ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE \__/ The doors of Heaven and Hell are adjacent and identical. -- Nikos Kazantzakis Jul 18 '05 #6

 P: n/a Erik Max Francis writes: Man, what a perfect gaffe on my part. The purpose of the do...while construct is to _eliminate_ the duplication. This should be: do: line = inputFile.readline() while line: ... I still like the assignment expression better. Jul 18 '05 #7

 P: n/a In article <7x************@ruckus.brouhaha.com>, Paul Rubin wrote: Joe Mason writes: > There's nothing implicit about an assignment expression. Except the return value. 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 Jul 18 '05 #8

 P: n/a Joe Mason writes: 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. Jul 18 '05 #9

 P: n/a Paul Rubin wrote: 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. -- __ Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/ / \ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE \__/ I am a gentlemen: I live by robbing the poor. -- George Bernard Shaw Jul 18 '05 #10

 P: n/a In article <7x************@ruckus.brouhaha.com>, Paul Rubin wrote: 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: (Snarfed from <67********************************@4ax.com>, by Dave K )from sets import Setfile('pruned_ips.txt', 'w').writelines( Set(file('ips.txt')) - Set(file('excluded_ips.txt')))This code relies on `writelines' accepting an iterable, sets returningtheir 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, -- Stefan Axelsson (email at http://www.cs.chalmers.se/~sax) Jul 18 '05 #11

 P: n/a Erik Max Francis writes: 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. 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. Jul 18 '05 #12

 P: n/a In article <7x************@ruckus.brouhaha.com>, Paul Rubin wrote: 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 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 Jul 18 '05 #13

 P: n/a Andrew Koenig wrote: 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 :" 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. -- Robin Munn rm***@pobox.com Jul 18 '05 #14

 P: n/a Joe Mason writes: 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. 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. Jul 18 '05 #15

 P: n/a >>>>> "Andrew" == Andrew Koenig writes: Andrew> Any loop that is currently written in the form Andrew> while True: 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. -- Ville Vainio http://tinyurl.com/2prnb Jul 18 '05 #16

 P: n/a On 19 Feb 2004 09:29:08 GMT in comp.lang.python, Stefan Axelsson wrote: (snip)Generators/iterators gives you e.g. the opportunity to write:(Snarfed from <67********************************@4ax.com>, by Dave K)from sets import Setfile('pruned_ips.txt', 'w').writelines( Set(file('ips.txt')) - Set(file('excluded_ips.txt')))This code relies on `writelines' accepting an iterable, sets returningtheir 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! :-) 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 inwhile loops or assignments as expressions is needed. In fact therelative awkwardness of the present state serves as an excellentopportunity 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 Jul 18 '05 #18

 P: n/a I don't like the syntax. I find the indentation counter-intuitive. Jul 18 '05 #19

 P: n/a On Wed, 18 Feb 2004 19:10:06 -0600, Jeff Epler wrote: On Wed, Feb 18, 2004 at 05:41:10PM +0000, Terry Carroll wrote: 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 placesyou need to handle a file in this way: Sure; there's no question that you can usually move awkward code constructs to a different location in the program. Jul 18 '05 #20

 P: n/a The do block is no safeguard against copy errors because it's optional. A comment saves the same purpose. Replace do: init() while cond(): body() by # init while init() while cond(): body() PEP-0315 shouldn't be added to Python. Mit freundlichen Gruessen, Peter Maas -- ------------------------------------------------------------------- Peter Maas, M+R Infosysteme, D-52070 Aachen, Hubert-Wienen-Str. 24 Tel +49-241-93878-0 Fax +49-241-93878-20 eMail pe********@mplusr.de ------------------------------------------------------------------- Jul 18 '05 #21

 P: n/a Peter Maas writes: The do block is no safeguard against copy errors because it's optional. A comment saves the same purpose. Replace do: init() while cond(): body() by # init while init() while cond(): body() No, you don't understand. The initialization is part of the loop. That is, the replacement for the do loop is while 1: init() if not cond: break body() PEP-0315 shouldn't be added to Python. I agree, but the reasoning has to go a bit further. Jul 18 '05 #22

 P: n/a In article , Dave K wrote: 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. Ah, my bad. I thought I cut the right attribution. At least I didn't claim that *I* had written it. :-) Stefan, -- Stefan Axelsson (email at http://www.cs.chalmers.se/~sax) Jul 18 '05 #23

 P: n/a Paul Rubin wrote: No, you don't understand. The initialization is part of the loop. That is, the replacement for the do loop is while 1: init() if not cond: break body() You are right, sorry. I was a bit hasty, thanks for the correction. I reread the PEP and now realize that it is about situations like while : So the setup code is there to guarantee at least one execution of the loop body. If this is the case, then the proposed form "do while" is misleading in my opinion. I would merge and to and solve the problem with code like do: breakif This would be clearer but I would mind this as well because I like the minimality of Python and I am completely satisfied with while 1: if : break Mit freundlichen Gruessen, Peter Maas -- ------------------------------------------------------------------- Peter Maas, M+R Infosysteme, D-52070 Aachen, Hubert-Wienen-Str. 24 Tel +49-241-93878-0 Fax +49-241-93878-20 eMail pe********@mplusr.de ------------------------------------------------------------------- Jul 18 '05 #24

 P: n/a Peter Maas wrote: do: breakif I forgot the situation do: breakif I was totally misguided by the term "setup" for . In my understanding a setup happens once like in C's for(;;) ... Mit freundlichen Gruessen, Peter Maas -- ------------------------------------------------------------------- Peter Maas, M+R Infosysteme, D-52070 Aachen, Hubert-Wienen-Str. 24 Tel +49-241-93878-0 Fax +49-241-93878-20 eMail pe********@mplusr.de ------------------------------------------------------------------- Jul 18 '05 #25

### This discussion thread is closed

Replies have been disabled for this discussion.