On 1 March 2017 at 19:37, Wolfgang Maier < wolfgang.ma...@biologie.uni-freiburg.de> wrote:
> I know what the regulars among you will be thinking (time machine, high > bar for language syntax changes, etc.) so let me start by assuring you that > I'm well aware of all of this, that I did research the topic before posting > and that this is not the same as a previous suggestion using almost the > same subject line. > > Now here's the proposal: allow an except (or except break) clause to > follow for/while loops that will be executed if the loop was terminated by > a break statement. > > The idea is certainly not new. In fact, Nick Coghlan, in his blog post > http://python-notes.curiousefficiency.org/en/latest/python_ > concepts/break_else.html, uses it to provide a mental model for the > meaning of the else following for/while, but, as far as I'm aware, he never > suggested to make it legal Python syntax. > > Now while it's possible that Nick had a good reason not to do so, I never really thought about it, as I only use the "else:" clause for search loops where there aren't any side effects in the "break" case (other than the search result being bound to the loop variable), so while I find "except break:" useful as an explanatory tool, I don't have any practical need for it. I think you've made as strong a case for the idea as could reasonably be made :) However, Steven raises a good point that this would complicate the handling of loops in the code generator a fair bit, as it would add up to two additional jump targets in cases wherever the new clause was used. Currently, compiling loops only needs to track the start of the loop (for continue), and the first instruction after the loop (for break). With this change, they'd also need to track: - the start of the "except break" clause (for break when the clause is used) - the start of the "else" clause (for the non-break case when both trailing clauses are present) The design level argument against adding the clause is that it breaks the "one obvious way" principle, as the preferred form for search loops look like this: for item in iterable: if condition(item): break else: # Else clause either raises an exception or sets a default value item = get_default_value() # If we get here, we know "item" is a valid reference operation(item) And you can easily switch the `break` out for a suitable `return` if you move this into a helper function: def find_item_of_interest(iterable): for item in iterable: if condition(item): return item # The early return means we can skip using "else" return get_default_value() Given that basic structure as a foundation, you only switch to the "nested side effect" form if you have to: for item in iterable: if condition(item): operation(item) break else: # Else clause neither raises an exception nor sets a default value condition_was_never_true(iterable) This form is generally less amenable to being extracted into a reusable helper function, since it couples the search loop directly to the operation performed on the bound item, whereas decoupling them gives you a lot more flexibility in the eventual code structure. The proposal in this thread then has the significant downside of only covering the "nested side effect" case: for item in iterable: if condition(item): break except break: operation(item) else: condition_was_never_true(iterable) While being even *less* amenable to being pushed down into a helper function (since converting the "break" to a "return" would bypass the "except break" clause). So while it is cool to see this written up as a concrete proposal (thank you!), I don't think it makes the grade as an actual potential syntax change. Cheers, Nick. -- Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/