Eh, what can I say? I guess I was paying too much attention to the baseball game. Yes, "else" handles the "fall off the end" termination, not the "exit early" termination. My apologies. I do think that having a way to spell "do this when the loop exits early" makes things clearer. So, perhaps while and for loops could someday grow except clauses. :-)
On Thu, Nov 2, 2017 at 5:04 AM, Steve D'Aprano <steve+pyt...@pearwood.info> wrote: > On Thu, 2 Nov 2017 12:49 pm, Skip Montanaro wrote: > > > I don't know. The word "then" doesn't connote different ways of exiting a > > loop to me ("else" doesn't really either, I will grant you that, but it's > > what we have). Here's how I would read things: > > > > - *while* some condition holds, execute the loop, possibly breaking > out, > > *then* do some finishing work > > - *for* each element in some sequence, execute the loop, possibly > > breaking out, *then* do some finishing work > > And that is exactly the behaviour of the for...else and while...else > construct. You're reading it correctly. > > When you say "possibly breaking out", I assume you mean breaking out of the > *entire* compound statement, because the alternative would be just silly. > The > alternative would be exactly equivalent to just following the loop with > some > unindented code: > > > while condition: > block > # on break we jump to here > finishing > > > In that case, it makes no sense to include a do-nothing "else" or "then" > keyword. > > To put it another way, if we are trying to infer the semantics of a > statement, > and can interpret it in one of two ways: > > - it does something > > - it does nothing > > then (with special case) of `pass`, we should always assume the first case, > thus resolving the ambiguity in favour of "Guido isn't an idiot who added a > pointless keyword" :-) > > > > In neither case does it seem to me that you execute the finishing work > only > > if you break out of the loop, but not if the loop terminates when the > while > > condition becomes false or the for loop's sequence is exhausted. > > If I'm reading you correctly, I think you are confused about the `else` > clause. It is incorrect to say that the `else` clause runs "only if you > break > out of the loop" (as you say). The `else` clause runs *after* the loop > completes, but NOT if you jump out with break/return/raise. > > If we don't jump out of the loop, the else block is equivalent to just > following the loop with unindented code: > > > for x in sequence: > block > else: > follows > > > is equivalent to: > > > for x in sequence: > block > follows > > > Hence, in the absence of any early exit from the loop, the `else` block > behaves more like an *then* rather than an "else". The behaviour of `else` > confused me utterly until I realised that the semantics of the compound > for...else was the loop to execute, then the `else` block. > > So why even bother with `else`? > > Unlike the second case, the `else` block is part for the compound for/while > statement. And so `break` doesn't just exit the loop, it exits the whole > compound statement, jumping past the `else`: > > for x in sequence: > block > else: > follows > # break jumps to here > more code > > > The motive for allowing this pattern is described here: > > https://shahriar.svbtle.com/pythons-else-clause-in-loops > > > > You might > > consider that while/then or for/then actually reads too much like > English, > > fooling you into interpreting it as English, opening you up to ambiguity. > > If you interpret it as English, it works fine. You run the loop, then you > run > the "then" clause. If you jump out of the loop (whether by return, raise or > break) you jump out of the *entire* statement, not just the loop part. > > There's no ambiguity because we can assume Guido wouldn't introduce a > pointless block keyword that does literally nothing except require an > indent. > > > > You might argue that "else" doesn't either, but it has the strangely nice > > property of actually being a bit clumsier to read, forcing the reader to > > learn and apply the precise rules of the programming language instead of > > infer the more ambiguous rules of English. > > If only that were true... > > There's a simple, obvious, but sadly WRONG plain English interpretation of > for...else, namely that the `else` clause runs if the for sequence was > empty: > > > for x in L: > pass > else: > # This is wrong! > print("L is empty") > > > and similar for while. That lead me astray for the longest time! And I'm > not > the only one. > > > > English and other natural languages aren't precise enough to serve as > > programming languages. > > Hmmm... I think Hypertalk might have something to say about that. > > And Inform7 I think would laugh in your face :-) > > > > > -- > Steve > “Cheer up,” they said, “things could be worse.” So I cheered up, and sure > enough, things got worse. > > -- > https://mail.python.org/mailman/listinfo/python-list > -- https://mail.python.org/mailman/listinfo/python-list