On Sun, Mar 20, 2016 at 01:16:50PM -0700, Andrew Barnert via Python-ideas wrote:
On Mar 20, 2016, at 11:12, Sven R. Kunze
wrote: Issues People I talked to suggested "else" as an alternative to "empty" because "empty is not quite clear". Unfortunately, "else" is already taken and is itself not quite clear. "then" has been proposed as an alternative for "else" in an attempt for proper understanding of "else". If that would be an accepted proposal, it would make room for "else" to be used for the usage of the "empty keyword proposed here.
Besides the backward compatibility issue, changing "else" to "then" would be horribly confusing. I suspect anyone who thinks that would be an improvement doesn't actually understand or like for...else, and they'd be happier just eliminating it, not renaming it.
"then" is my idea, and not only do I understand "for...else", but I like it and use it, and certainly don't want to eliminate it. I just hate the keyword used. Let me just start by saying that I realise that actually changing "for...else" to "for...then" is at least 8 years too late, so I know this is a non-starter. It would be particularly confusing to change "else" to "then" AND add a new "else" with different semantics at the same time.
An else clause is testing that no break was hit inside the loop. Look at a typical example:
That's one way of thinking about it. But I don't think it is helpful to think of it as setting an invisible flag "a break was hit inside the loop", and then testing it. I think that a more natural way to think about it is that "break" jumps out of the entire for...else compound statement. This has the big advantage that it actually matches what the byte code does in all the versions I've looked at. The "else" block is *unconditionally* executed after the "for" block. There's no "if not flag". Hence "then" is a better name for the construct: "for ... then ...". "break" doesn't set a flag, it jumps right out of the "for...else" statement altogether, not just out of the loop part, but the "else" part as well. (As I said, this matches what the byte code actually does.) As a beginner, I spent a very long time completely perplexed and confused by the behaviour of "for...else" because I understood it to mean "run the for block, *or else* run the else block". In other words, I understood from the keyword that "else" ran *if the for block didn't*, i.e. when the loop iterator is empty. A perfectly natural mistake to make, and I'm not the only person to have made it. This (wrong, incorrect) interpretation matches the most common and familiar use of "else", namely in if...else statements: if ...: a else: b You can get a, or b, but not both. In English, "else" represents an alternative. This does not come even close to matching the behaviour of for...else, which (in the absense of a "break" executes a *and* b, rather than a *or* b: for ...: a else: b I'm not Dutch, but I think that "else" is not a good name for a block of code which unconditionally executes after the for/while/try block. I think it's also unfortunately that it often looks like an indentation error: for x in seq: do_stuff() if condition: break else: do_more() I've seen people "fix" the indentation on code like this and wonder why the code then does the wrong thing. But, like I said, we're stuck with it, and I'm not seriously proposing a change. I think we'd be better off now if the keyword had been "then" from the beginning, but the pain of changing it *now* outweighs the benefit. -- Steve