Remember that a good number of multi-break situations can be better handled by treating the entire loop as a search operation, refactoring it into a function, and having the multi-break become âcool, we found the thing, return a resultâ. So you have to also show cases where this would not be appropriate.
Actually I donât agree that this needs to be shown for the same reason that for loops donât need to be shown to be inappropriate for list comprehensions to be deemed useful. Given that what I am proposing is syntactic sugar, the only thing that does need to be shown, IMO, is that this is a good suggestion as far as syntactic sugar goes since nobody would ever be required not to use any previous methods
âtry:â has always been fast and I believe it became even faster, or even free at runtime in 3.11 (or possibly 3.12) due to better compilation. It is already Pythonâs general âbreak executionâ mechanism.
Yes, it works but itâs far uglier:
- You need to look at the except blocks to understand why they are there if you didnât write the program
- They are ambiguous at best since try-exceptâs main purpose is not this
- It adds another tab level for each place you want to stop, which pushes your code farther to the right and is never ideal
- Itâs a lot more work to remove from code than the notation I am proposing
- Much more importantly, there would need to be ONE try-except block FOR EACH LEVEL in order to achieve the same leve of control plus two excepts, one for continue and one for break
The need for multiple-loop breaks is really much rarer than that of single loop breaks, so I donât think we need a special form for the latter.
Well, this suggestion has come up multiple times throughout the years and you can find a lot of threads and Reddit posts asking about this subject online. This shows that, even if it happens a lot less frequently, it does still happen a good deal. Not to mention, there are multiple languages that did deem this useful enough to implement
The obvious fix for that ugly code is to refactor into a function
This is exactly one of the reasons why we need this syntactic sugar. If something must be refactored in order for you to achieve relatively basic functionality, I think that this is, at least, not ideal.
Not to mention this solution does not include the possibility of also using âcontinueâ at any level, as I am proposing.
As for try and except, this approach is simultaneously compatible with both break and continue if we raise two different exceptions but is this really what try-except was meant for? For the reasons I stated above, I think that this notation is far less clear and certainly not ideal
You have missed the point that if you are adding or removing nested loops, all the break 3 numbers will need to be changed or you will silently break out too many or two few levels. And that is easy to miss
Adding or removing nested loops is a big change to the code. Something pretty big needs to have changed for you to do decide to completely change the flow of your program. Compared to that, changing a single number should be trivial.
break 3 as you have it tells the interpreter to break three times, which is fine, but it makes it hard for the reader and writer to tell what that means. After you have done the break three times, where in the code are you?
I do agree that label breaks are better in this one particular respect but I donât necessarily think that they would be better as the sole possible notation. I think numbers suffice but both notations could be offered if there is no technical impediment. At the very least, I would argue that numbered breaks are much, much easier than telling where you you are in the code if we use one of the currently available notations:
for sport in all_sports:
try:
for player in all_players:
try:
for player_tables in all_tables:
try:
for version in player_tables:
if condition:
# things have gone wrong, bail out early.
raise MultiBreak
block()
except MultiBreakThree:
break
except MultiContinueThree:
break
except MultiBreakTwo:
break
except MultiContinueTwo:
break
except MultiBreakOne:
break
except MultiContinueOne:
break