On Sun, Mar 05, 2017 at 01:17:31PM +1000, Nick Coghlan wrote: > I forget where it came up, but I seem to recall Guido saying that if he > were designing Python today, he wouldn't include the "else:" clause on > loops, since it inevitably confuses folks the first time they see it.
Heh, if we exclude all features that confuse people the first time they see it, we'd have to remove threads, Unicode, floating point maths, calls to external processes, anything OS-dependent, metaclasses, classes, ... :-) It took me the longest time to realise that the "else" clause didn't *only* run when the loop sequence is empty. That is, I expected that given: for x in random.choice(["", "a"]): # either empty, or a single item print("run the loop body") else: print("loop sequence is empty") That's because it *seems* to work that way, if you do insufficient testing: for x in []: raise ValueError # dead code is not executed else: print("loop sequence is empty") It is my belief that the problem here is not the else clause itself, but that the name used is misleading. I've seen people other than myself conclude that it means: run the for-loop over the sequence otherwise the sequence is empty, run the ELSE block I've seen people think that it means: set break_seen flag to false run the for-loop if break is executed, set the break_seen flat to true then break if break_seen is false, run the "ELSE NOT BREAK" clause and consequently ask how they can access the break_seen flag for themselves. Presumably they want to write something like: run the for-loop if break_seen is true, do this else (break_seen is false) do that I think that the name "else" here is a "misunderstanding magnet", it leads people to misunderstand the nature of the clause and its implications. For example, I bet that right now there are people reading this and nodding along with me and thinking "maybe we should rename it something more explicit, like "else if no break", completely oblivious to the fact that `break` is NOT the only way to avoid running the `else` clause. I believe that the name should have been "then", not "else". It describes what the code does: run the for-block THEN run the "else" block There's no flag to be tested, and the "else" block simply runs once, after the for-loop, regardless of whether the for-loop runs once or ten times or zero times (empty sequence). To avoid running the "else" ("then") block, you have to exit the entire block of code using: - break - return - raise which will all transfer execution past the end of the for...else (for...then) compound statement. Since I realised that the else block merely runs directly after the for, I've never had any problem with the concept. `break` merely jumps past the for...else block, just as `return` exits the function and `raise` triggers an exception which transfers execution to the surrounding `except` clause. -- Steve _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/