Friday, April 17, 2015

Loopy else in Python

I love Python.  Yet, there are some minor things in the language that I find baffling...

Python loop statements (for/while) include an optional else clause whose behaviour is very counter intuitive.  In fact, it is so "bad" that Brett Slatkin, author of Effective Python, wrote as one of his 59 specific ways to write better Python:

Item 12: Avoid else Blocks After for and while Loops.

In fact, Guido himself wrote in 2009:

I would not have the feature at all if I had to do it over.

(My initial preference, when I learned about the meaning of else in those loops, was to wonder why "ifnobreak" had not bee used as a keyword instead; later I saw Raymond Hettinger suggest simply "nobreak" which I thought was both more readable and a better idea. [You can see Hettinger explain why in this video.]  However, Guido also mentioned in the above quoted message "I would *not* choose another keyword.")

In the official Python tutorial, when the else clause is discussed, we find these two interesting statements:

Yes, this is the correct code. Look closely: the else clause belongs to the for loop, not the if statement.
(I don't know about you, but when I read some similar warning in a tutorial, my immediate reaction is to question why it was done like this in the first place since it is recognized as being far from obvious.)

When used with a loop, the else clause has more in common with the else clause of a try statement than it does that of if statements...
This is yet another acknowledgement that people might be confused about the meaning of "else", since they mostly see it with "if" statements.  

 And it seems it's going to get only worse.  In a new PEP, we see that another similar else clause is proposed with the similar semantic...

async for TARGET in ITER:
 Why, oh why can we not introduce a clearer keyword (like nobreak) and stop introducing yet more examples of confusingly named clause...