for / while else doesn't make sense

Ethan Furman ethan at stoneleaf.us
Fri May 20 19:58:14 EDT 2016


On 05/20/2016 04:55 AM, Jon Ribbens wrote:
> On 2016-05-20, Steven D'Aprano wrote:
>> On Fri, 20 May 2016 03:55 am, Jon Ribbens wrote:

>>> I guess we should thank our lucky stars that you don't have a time
>>> machine then, since that change would very much be one for the worse
>>> in my opinion. for...else is perfectly straightforward and clearly
>>> the right keywords to use. for...then would be entirely wrong.
>>
>> "Entirely" wrong? "Clearly" the right keyword? "Perfectly" straightforward?
>>
>> They are extremely strong words given the posts where *even the defenders*
>> of "else" have admitted that it is a hard keyword to understand. But that's
>> okay. Maybe you've thought of something the rest of us haven't, and have an
>> entire consistent mental model of for...else that is easy to understand and
>> makes it "perfectly straightforward and clearly the right keyword".
>>
>> Can you explain your model which makes "else" appropriate?
>
> Certainly. "else:" is (almost?) invariably used in the situation where
> you are iterating through something in order to find a value which
> matches a certain condition. So the "for:" block means "find this
> value" and the "else:" means "else do this".

I'm happy that you have a working mental model for for/else (seriously, 
I am) but please don't discount the confusion and consternation for the 
many folks who don't start with that mental model.

The number of times I have /wanted/ to use the for/else structure for 
searching is small (and I remember them both ;) -- every other time what 
I wanted was an _else_ that ran iff the iterable was already empty when 
the _for_ encountered it.


>> because like many people, my mental model was "the for block runs, OR ELSE
>> the else block runs". This *incorrect* model seems like it works: if you
>> set seq=[], say, it prints "seq is empty" as expected.

> The problem there is that the mental model is *completely* wrong.

D'oh.  Completely wrong, but easy to guess because of the similarity 
with if/else.


>> I never would have thought of that model if it had been called "then":
>>
>> for x in seq:
>>      pass
>> then:
>>      print("executes after the for block completes")
>
> I would find that very confusing. "then:" makes it sound like
> executing that block is the usual case, when in practice it is
> usually the exception - the fallback code if the expected value
> was not found.

If you don't take the extra step of _break_ it is the usual case.  Most 
of my for loops always run all the way through, so why have an else? 
Two possible reasons:

- the loop didn't run at all
- the loop didn't run all the way

Guido picked the one that was obvious to him (him being Dutch and all ;) .

I just read Nick's post about it, and while it helps, I think the 
syntactic similarity between try/else and for/else (did the block run 
without error) is dwarfed by the semantic difference: a try/else else 
block runs if nothing /bad/ happened whereas a for/else else block runs 
if something bad /did/ happen; to wit, the thing you were looking for 
was not found (or your loop didn't run at all ;) .

But as others have said, this isn't going to change now, and I'm okay 
with that.  But, please, be a bit more understanding of those who don't 
immediately grok the for/else and while/else loops.

--
~Ethan~



More information about the Python-list mailing list