[Python-ideas] for/else statements considered harmful

Nathan Schneider nathan at cmu.edu
Thu Jun 7 06:29:46 CEST 2012

```On Wed, Jun 6, 2012 at 5:53 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:
> On Thu, Jun 7, 2012 at 9:58 AM, Bruce Leban <bruce at leapyear.org> wrote:
>> If we could go back in time I would completely agree. But since we can't,
>> flipping meaning of else would be too error inducing and therefore not at
>> all likely.
>
> The meaning of the "else:" clause on for and while loops is actually
> much closer to the sense in "try/except/else" sense than it is to the
> sense in "if/else".
>
> Consider the following:
>
>    for x in range(20):
>        if x > 10:
>            break
>    else:
>        # Reached the end of the loop
>
> As an approximate short hand for:
>
>    class BreakLoop(Exception): pass
>
>    try:
>        for x in range(20):
>            if x > 10:
>                raise BreakLoop
>    except BreakLoop:
>        pass
>    else:
>        # Reached the end of the loop
>
> It's not implemented anything like that (and the analogy doesn't hold
> in many other respects), but in terms of the semantics of the
> respective else clauses it's an exact match.
>
> Part of the problem is that the "else:" clause on while loops is often
> explained as follows (and I've certainly been guilty of this), which I
> now think exacerbates the confusion rather than reducing it:
>
> The following code:
>    x = 0
>    while x < 10:
>        x += 1
>        if x == y:
>           break
>    else:
>        # Made it to 10
>
> Can be seen as equivalent to:
>
>    x = 0
>    while 1:
>        if x < 10:
>            pass
>        else:
>            # Made it to 10
>        x += 1
>        if x == y:
>           break
>
> This actually ends up reinforcing the erroneous connection to if
> statements, when we really need to be encouraging people to think of
> this clause in terms of try statements, with "break" playing the role
> of an exception being raised.
>
> So I think what we actually have is a documentation problem where we
> need to be actively encouraging the "while/else", "for/else" ->
> "try/except/else" link and discouraging any attempts to think of this
> construct in terms of if statements (as that is a clear recipe for
> confusion).
>
> If anything were to change at the language level, my preference would
> be to further reinforce the try/except/else connection by allowing an
> "except break" clause:
>
>    for x in range(20):
>        if x > 10:
>            break
>    except break:
>        # Bailed out early
>    else:
>        # Reached the end of the loop

I like this proposal, or perhaps

while ...:
...
with break:
# Bailed out early
else:
# Reached the end of the loop

...which avoids any conceptual baggage associated with exception
handling, at some risk of making people think of context managers.

For what it's worth, I don't use the loop version of 'else' to avoid
confusing myself (or the reader of my code). But in my experience the
use case 'else' is intended to solve is probably less common than (a)
checking whether the loop was ever entered, and (b) checking from
within the loop body whether it is the first iteration.

Nathan

> To critique the *specific* proposal presented at the start of the
> thread, there are three main problems with it:
>
> 1. It doesn't match the expected semantics of a "finally:" clause. In
> try/finally the finally clause executes regardless of how the suite
> execution is terminated (whether via an exception, reaching the end of
> the suite, or leaving the suite early via a return, break or continue
> control flow statement). That is explicitly not the case here (as a
> loop's else clause only executes in the case of normal loop
> termination - which precisely matches the semantics of the else clause
> in try/except/else)
> 2. As Bruce pointed out, the meaning of the else: clause on loops
> can't be changed as it would break backwards compatibility with
> existing code
> 3. The post doesn't explain how the proposed change in semantics also
> makes sense for while loops
>
> Cheers,
> Nick.
>
> --
> Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas

```