On Sat, Sep 20, 2008 at 1:26 PM, Arnaud Delobelle arnodel@googlemail.com wrote:
On 20 Sep 2008, at 20:44, Josiah Carlson wrote:
On Sat, Sep 20, 2008 at 11:35 AM, Arnaud Delobelle
[...] I think that this would look better:
while True: do something break if condition do something else
It gets worse ;)
break if condition
Also implies...
continue if condition
That's true, why not? I don't use use continue so much but it seems logical.
Never mind
break if condition else continue continue if condition else break
No that would be silly.
Why? It follows directly from conditional expressions as well as your proposed syntax?
Because who would want to write... break if condition continue
or continue if condition break
The problem is: when would you need to do this? I pointed out in my original post that almost half of uses of 'break' in the py3k python source come immediately after an 'if'. Now I have never used or seen this:
if condition: break continue
Just because *you've* never seen it, doesn't mean it shouldn't be a valid control structure.
while ...: #do some stuff if some_condition: #do some other stuff break if other_condition else continue #do yet some other stuff which is skipped by the line above
You are probably thinking; "but Josiah, that secondary clause could be held in an else clause", and I would confirm that. But then I would point out that this one example cannot possibly encompass the entirety of potential uses for the feature.
I would then point out that the cases that you are trying to fix, 'break if condition', you inadvertently hide the *flow control* in a mass of words. Break and continue are currently happy little single-word statements. Even when trailing on the same line as an 'if', there is a colon separating them from the if and condition. I would argue that this punctuation is critical for understanding the idea "something conditional is happening here to your flow control". Without that colon, break/continue get to be the only two statements that get an optional 'if' suffix, whose only purpose seems to be to reduce line count.
What would be the point of spelling it 'break if condition else continue'? It would even defeat the idea behind my suggestion, which is to make the structure of a loop more obvious when you scan code: you can spot the 'break if' (and 'continue if'!) statements just by scanning the left hand side of the loop body.
But this doesn't help in that. Break and continue are *already* immediately to the right of whitespace (unless someone tries to make it a single line), and while the *simple* case of...
for ... in ...: ... if condition: break ...
... is common, that doesn't mean that the following isn't ...
for ... in ...: ... if condition: ... if other_condition: break ... ...
Which isn't greatly improved by your suggestion.
But if we can break or continue, why not others? What's wrong with a raise (especially if we surround everything with parens...)?
(raise Exception("X")) if condition
Never mind assert, yield, throw, return, ... I hope this horse is dead now.
You have implied one reason why not: raise, assert, yield, throw, return all take an argument which can be an if-expression, so this would make those statements difficult to parse if you are human (and I suspect impossible if you are the Python parser).
No, I pointed out a syntax that is unambiguous. How do I know it is unambiguous? Because it's used by the yield *expression* in Python 2.5 and later:
x = (yield y) + 1
Though maybe that's a vote against yield, because the rest are statements and don't return anything.
The fact that neither break nor continue take arguments makes them very 'poor' in the amount of meaning they convey. That's why a lot of people feel like writing the following in one single line.
if condition: break
It's not a question of amount of meaning, it's a question of context. I've heard explanations at least as much saying that they thought that not having an indented trailer makes the code "prettier", "shorter", "easier to understand" as I've heard the opposite from reviewers arguing against the single-line if idiom.
Moreover, because we don't have a 'do .. while' construct, 'break' is more important than in other languages to shape loops (especially while loops), so I thought it would be useful to make it easier to spot. The same argument can be made about 'continue' of course.
Perfectly reasonable, but then the base isn't so much...
while 1: ... if condition: break ...
it's really...
while 1: ... if condition: break
Which *has* an idiom in Python.
first = 1 while first or condition: first = 0 ...
And before you come back with "but that's not as fast", I'll point out that an assignment to a local and an or computation are pretty darn fast. With psyco; even faster:
def test1(n):
... i = 0 ... while 1: ... i += 1 ... if i >= n: break ...
def test2(n):
... i = 0 ... first = 1 ... while first or n > i: ... first = 0 ... i += 1 ...
t = time.time(); test1(10000000); time.time()-t
1.0160000324249268
t = time.time(); test2(10000000); time.time()-t
1.1559998989105225
import psyco psyco.full() t = time.time(); test1(1000000000); time.time()-t
1.4059998989105225
t = time.time(); test2(1000000000); time.time()-t
1.4060001373291016
Worst-case, 15% more time without psyco for the *simplest* possible loop. Less difference as the body of the while increases. With psyco: no difference.
But what about, "that's not as pretty as 'break if condition'"? Ok, it's not as pretty. But I would then point out that at least now, you don't have one of those "while 1:" loops that can raise eyebrows.
- Josiah