for / while else doesn't make sense

Steven D'Aprano steve at pearwood.info
Tue Jun 14 23:12:19 EDT 2016


On Wed, 15 Jun 2016 01:33 am, Rustom Mody wrote:

> On Tuesday, June 14, 2016 at 8:13:53 AM UTC+5:30, Steven D'Aprano wrote:
>> No. The sun exploding was me gently mocking you for your comment
>> disputing the "unconditional" part. Yes, you are technically right that
>> technically the "else" block will only run if no "break" is reached, and
>> no "return" is reached, no exception is raised, also that os._exit or
>> os.abort aren't called, the CPU doesn't catch fire, and the world isn't
>> destroyed.
>> 
>> If we try to enumerate all the things which could prevent the "else"
>> block from running, we'll be here for decades. But, and this is the point
>> that everyone seems to have missed, * every single one of those things*
>> is completely independent of the for...else statement.
>> 
>> *Including* the presence or absence of a "break".
> 
> This is real wild:  A break that is inside a for is independent of the
> for?!?!

If that's what I said, you would be right to question me. But that's not
what I said.

It is legal syntax to have for...else without a break, or a break inside a
for block with no else. And, if you really want to nitpick, you can even
have a break statement without a for. (Just stick it inside a while loop
instead.)

I know that's it's great fun to pick at nits without making a good faith
effort to communicate, but honestly Rustom, your following comments do
suggest that you understood what I was saying.


[...]
> This *desire* for what you call isolation is a standard tenet of
> semantics and is right
> 
> It is called compositionality
> 
> Inn programming:
> https://en.wikipedia.org/wiki/Denotational_semantics#Compositionality
> 
> More general linguistics:
> https://en.wikipedia.org/wiki/Principle_of_compositionality

Thanks for that.


> However gotos break compositionality unless one introduces heavy artillery
> like continuations
> 
> And break is a euphemism for goto

Sort of. A break is a jump, and a goto is a jump, but apart from that,
they're not really the same thing. A goto can jump (almost) anywhere.
Depending on the language, they can jump into the middle of functions, or
into the middle of loops. That's what makes them powerful enough to break
compositionality. But break can only jump to a single place: to the
statement that follows the for...else compound statement. It's more like a
return than a goto.

You can reason about for...else without the break, then reason about what
the break does. This isn't hard, and its what people do even in the common
use-case:

for x in seq:
    process(x)
    if condition:
        break
else:
    fnord()
spam()

"If the condition is never true, then we loop through seq, calling
process(x) each time, then call fnord(), then call spam(). If the condition
becomes true at some point in the loop, we stop looping, and go straight to
calling spam()."

We can reason about the condition is true case separately from the condition
is false case. And we can do so without imagining that there is an
invisible "did_not_break" flag, or needing a second mental model to
understand this ever-so-slightly more complex example:

for x in seq:
    process(x)
    if condition:
        break
    else:
        foo()
else:
    fnord()
spam()



-- 
Steven



More information about the Python-list mailing list