Hello,
It seems to me that a lot of the time that I use a break statement, it
is directly after an if. Typically:
while True: do something if condition: break do something else
I don't like so much the if .. break which is spread over two lines.
Of course I could write
while True: do something if condition: break do something else
It doesn't read so well either IMHO. I think that this would look
better:
while True: do something break if condition do something else
Now I've had a quick look on a py3k tree (a bit old, rev. 64270):
$ grep -r --include "*.py" break py3k/ | wc -l 1418
1418 uses of the break statement in the py3k python code.
$ grep -r --include "*.py" -B 1 break py3k/ | grep if | wc -l 680
Of which 680 are immediately preceded by an if statement
$ grep -r --include ".py" "if .: break" py3k/ | wc -l 107
Of which 107 are preceded by an if on the same line
This means that:
(I know my greps will include a few false positive but I don't think
they are significant :)
-- Arnaud
On Sat, Sep 20, 2008 at 11:35 AM, Arnaud Delobelle arnodel@googlemail.com wrote:
Hello,
It seems to me that a lot of the time that I use a break statement, it is directly after an if. Typically:
while True: do something if condition: break do something else
I don't like so much the if .. break which is spread over two lines. Of course I could write
while True: do something if condition: break do something else
It doesn't read so well either IMHO. I think that this would look better:
while True: do something break if condition do something else
For some reason this suggestion reminds me of Icon.
Anyway, so I take it this suggestion is to extend the break statement to have an 'if' trailer? Or are you trying to make 'break' an expression?
If you are after the former, the problem with that is that the
special-casing of 'if' might confuse people because they will suddenly
want an 'else' clause. Adding that might then cause a naive user to
see break if x
and then think 'break' is an expression.
Which leads to its own issues. How do you implement 'break' as an
expression? It doesn't make much sense to have fxn(a, break, b)
inside a loop. And you can't say 'break' can only appear in the true
clause of an 'if' expression as that is too specialized and will lead
to potential misuse of the statement (or at least an attempt).
I don't see enough benefit from the change to warrant dealing with any of the above issues.
-Brett
On Sat, Sep 20, 2008 at 12:07 PM, Brett Cannon brett@python.org wrote:
On Sat, Sep 20, 2008 at 11:35 AM, Arnaud Delobelle arnodel@googlemail.com wrote:
Hello,
It seems to me that a lot of the time that I use a break statement, it is directly after an if. Typically:
while True: do something if condition: break do something else
I don't like so much the if .. break which is spread over two lines. Of course I could write
while True: do something if condition: break do something else
It doesn't read so well either IMHO. I think that this would look better:
while True: do something break if condition do something else
For some reason this suggestion reminds me of Icon.
Anyway, so I take it this suggestion is to extend the break statement to have an 'if' trailer? Or are you trying to make 'break' an expression?
If you are after the former, the problem with that is that the
special-casing of 'if' might confuse people because they will suddenly
want an 'else' clause. Adding that might then cause a naive user to
see break if x
and then think 'break' is an expression.
Which leads to its own issues. How do you implement 'break' as an
expression? It doesn't make much sense to have fxn(a, break, b)
inside a loop. And you can't say 'break' can only appear in the true
clause of an 'if' expression as that is too specialized and will lead
to potential misuse of the statement (or at least an attempt).
I don't see enough benefit from the change to warrant dealing with any of the above issues.
It gets worse ;)
break if condition
Also implies...
continue if condition
Never mind
break if condition else continue continue if condition else break
Because who would want to write... break if condition continue
or continue if condition break
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.
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.
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
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 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).
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
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.
-- Arnaud
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 Carlson wrote: >
break if condition else continue continue if condition else break
No that would be silly.
Why? It follows directly from conditional expressions
In my view, backwards conditional expressions were Guido's worst mistake. This proposal and comments like the above partly illustrate why I think so.
On Sun, Sep 21, 2008 at 11:36 AM, Terry Reedy tjreedy@udel.edu wrote:
Josiah Carlson wrote: >
break if condition else continue continue if condition else break
No that would be silly.
Why? It follows directly from conditional expressions
In my view, backwards conditional expressions were Guido's worst mistake. This proposal and comments like the above partly illustrate why I think so.
I don't know if it was his worst mistake in language design, but I agree it did open the door for such proposals.
On 21 Sep 2008, at 19:36, Terry Reedy wrote:
Josiah Carlson wrote: >
break if condition else continue continue if condition else break
No that would be silly. Why? It follows directly from conditional expressions
In my view, backwards conditional expressions were Guido's worst
mistake. This proposal and comments like the above partly
illustrate why I think so.
I don't know what was the motivation for including conditional
expression in the language, but:
condition and x or y
is better replaced with:
x if condition else y
So from a pragmatic point of view, if-expressions work as some kind of
"vaccine" against the above.
-- Arnaud
On 21 Sep 2008, at 17:48, Josiah Carlson wrote:
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?
I don't think it does. This has nothing to do with conditional
expressions.
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.
What I'm saying is that it doesn't occur often enough to be worried
about it. OTOH, 'if condition: break' occurs very commonly.
[...]
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.
Reducing line count was definitely not my aim (see just below)
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 ...
You forget:
if condition: break
for ... in ...: ... if condition: ... if other_condition: break ... ...
Which isn't greatly improved by your suggestion.
There's some truth in this.
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.
Yes, they're statements, I wouldn't want them to be surrounded by
parentheses. I only proposed "break if" (and "continue if", perhaps),
I don't see why every statement should be equipped with a trailing
"if" as a necessary consequence.
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.
if condition: break
on a single line happens a lot, whether liked by reviewers or not.
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
I don't agree with that: the absence of do .. while liberates the loop
construct in python from its constraints and the first form above
becomes more common.
Which has an idiom in Python.
first = 1 while first or condition: first = 0 ...
I would not use this, not because it is slower, but because it is
uglier.
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
My tests:
t1=timeit.Timer("test1(10000000)", "from loops
import
test1").timeit(5)
t2=timeit.Timer("test2(10000000)", "from loops import
test2").timeit(5)
t1, t2
(5.3120660781860352, 7.4985768795013428)
t2/t1
1.4116121240084343
test1 is 41% faster, that is not negligible. I don't think the
fact
that psyco optimises the code is a valid argument.
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.
Well, they don't raise my eyebrows :)
Anyway, there hasn't been a flurry of positive responses so far so I
don't think this is going to go much further than this reply...
-- Arnaud
On 20 Sep 2008, at 20:07, Brett Cannon wrote:
On Sat, Sep 20, 2008 at 11:35 AM, Arnaud Delobelle arnodel@googlemail.com wrote: >
[...] I think that this would look better:
while True: do something break if condition do something else
For some reason this suggestion reminds me of Icon.
Anyway, so I take it this suggestion is to extend the break statement to have an 'if' trailer? Or are you trying to make 'break' an expression?
No I wasn't suggesting this.
If you are after the former, the problem with that is
that the
special-casing of 'if' might confuse people because they will suddenly
want an 'else' clause. Adding that might then cause a naive user to
see break if x
and then think 'break' is an expression.
I thought that the meaning of e.g.
break if x < 1
was clear and unambiguous.
I don't know if some people do, but I personally have never felt the
need to write something like:
expression1 if condition else expression2
on its own on a line. So I wouldn't find the above 'break if x < 1'
statement confusing :)
Which leads to its own issues. How do you implement
'break' as an
expression? It doesn't make much sense to have fxn(a, break, b)
inside a loop. And you can't say 'break' can only appear in the true
clause of an 'if' expression as that is too specialized and will lead
to potential misuse of the statement (or at least an attempt).
I certainly wouldn't want 'break' to be an expression.
I don't see enough benefit from the change to warrant dealing with any of the above issues.
Fair enough!
-Brett
-- Arnaud
Arnaud Delobelle wrote:
while True: do something if condition: break do something else
I think mid-test/multi-test loops are common enough that it might be worth explicit syntax to pick out the loop exit points:
while True:
do something
andwhile not condition:
do something else
(or 'and while' if one wanted to save on reserved words. 'not condition' because the logic is reversed from the quoted example.)
Similarly for 'if', I often find myself with unsatisfactory constructs like:
if condition:
do something
if othercondition:
success
else:
failure
else:
failure
I would like to flatten together the else clauses:
if condition:
do something
andif othercondition:
success
else:
failure
On Thu, Sep 25, 2008 at 6:34 AM, Andrew Clover and-dev@doxdesk.com wrote:
Arnaud Delobelle wrote:
while True: do something if condition: break do something else
I think mid-test/multi-test loops are common enough that it might be worth explicit syntax to pick out the loop exit points:
while True: do something andwhile not condition: do something else
That breaks the flow of the loop, and it is not visually clear that "do something else" is a part of the while loop. This is one of many reasons why switch/case statements failed.
(or 'and while' if one wanted to save on reserved words. 'not condition' because the logic is reversed from the quoted example.)
Similarly for 'if', I often find myself with unsatisfactory constructs like:
if condition: do something if othercondition: success else: failure else: failure
I would like to flatten together the else clauses:
if condition: do something andif othercondition: success else: failure
That becomes ambiguous in the case of more than 2 levels of if, never mind needing andelif, never mind being wholly unreadable by non-english speakers. Flat is better than nested, but nested indents do offer clarity about what code does. A brief skimming of the above tells me nothing about the control flow of the code.
Josiah Carlson wrote:
On Thu, Sep 25, 2008 at 6:34 AM, Andrew Clover and-dev@doxdesk.com wrote:
Arnaud Delobelle wrote:
I think mid-test/multi-test loops are common enough that it might be worth explicit syntax to pick out the loop exit points:
while True: do something andwhile not condition: do something else
That breaks the flow of the loop, and it is not visually clear that "do something else" is a part of the while loop.
while True: do something breakif condition do something else continueif condition do some other thing
I don't know if you can start a key word with * but it does pick out the loop exit points without complicating the indentation.
Is it terribly bad? It was rejected a few months ago, but possibly because it was lumped in with some other stuff.
The only alternative I can think of is syntax colouring: recommend that keywords that break the flow should be treated differently from other keywords in Python code editors. eg break, continue, return, exit in bold red.
-- jh