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/

Reply via email to