Personally, I think we should keep it simple. Tim’s proposal has a tight scope, with a clear justification to improve the common use case.
IMO this isn’t something that will be used a huge amount, but that’s perfectly fine.
I strongly agree with this - there seems to be a common misconception in the Ideas category that language features need to be instantly understandable with no prior knowledge. Whereas what’s far more important, as you say, is whether it sticks in your mind after you’ve learned it.
Python has had for/else and while/else from the start, their syntax has never been intuitive to anyone, and never will be. They’re nevertheless useful. As already said to @storchaka, adding if break: doesn’t add new obscurity so much as it clarifies what’s already been obscure since the start. “Ah! I get into the if break: suite if there was a break, and the else: suite if there wasn’t”.
So long as Python loops have else: clauses (“forever” is a safe bet), that will remain so.
In this case, maybe could allow extra flexibility by not making it one statement.
while True:
break
# caches whether break has occurred
# do whatever one wants here
a = 1
b = 2
if condition:
# do stuff
elif break:
# do stuff
else:
# do stuff
And instead of modifying for/while, modification is needed for if/elif/else.
Then could also allow:
if not break:
# do stuff
This would pretty much replace else extensions for anyone who finds it unreadable.
No interest from me in “hyper-generalization” here. Maybe in a different topic. This topic is about an objectively minor tweak to the existing semantics and spelling of loop/else constructs.
That appears to be the preferred approach when needing to break out of multiple levels of loop (as your example did), but is generally gross overkill for the typically simpler “one loop level” cases. An additional level of indentation to stuff things in try/except, and “serious” code typically creates its own exception class.
I do that too, but I’m only aiming here at improving the more common one-loop cases, where break on its own is wholly sufficient.
Would if break and ...: also be valid? What about if not break? I assume the answer is no, and that is IMO a problem - introducing magic multiple keyword sequences that look like they are a different feature is going to cause confusion.
I.e. the rule for if statements is “there is an expression that is being evaluated and if it’s truthy that is what happens”. break is not an expression, it doesn’t evaluate to a value and it isn’t truthy. While I somewhat like how it reads, I believe this will cause an infinite amount of confusion - even more than the else clause.
(I am however strongly opposed to using elif - I would always assume it is related to the else construct, when it is semantically the exact opposite. And everyone who learned about elif and else in the context of if-statements will do the same the first time)
Nobody here yet has expressed the slightest confusion about what if break: is intended to mean in context. Quite the contrary, everyone appears to grasp it at once.
So I doubt the “confusion” spin. It’s a tiny learning curve, sure, but one-and-done.
if not break: could be added, but that’s already spelled else:, and “one obvious way” rules. if break and ... just reads like gibberish to me, so, no, I would not support that, no more than if as:. if break: is close to its plain English meaning.
That’s because you explained it in the OP, and people are taking your proposal as given. That’s not how anyone else will encounter it–they’ll likely encounter it by reading some code that uses it.
Elaborating a bit on how the above syntax could work for the following idea:
We can make break work like a match - case:
for x in ...:
if cond1:
break "success", result
elif cond2:
break "fail", reason
break ("success", result):
... # On success
break ("fail", reason):
... # On fail
break:
.... # Wildcard
else:
.... # No result
While break: is a syntax error now, break; is not, and in the editor font I usually use for writing code the difference between a semicolon and a colon is tiny. Compounded by that the only difference in typing them is whether the SHIFT key is depressed. Too error-prone for me, both for writing and reading.
if plays perfectly with the existing else. break/else just looks confused .
This felt like a strong argument at first glance, but then I realized the actual difference lies in the lines following it - a break: clause will be followed by indented code, which makes it super obvious