[Python-ideas] for/except/else syntax

Steven D'Aprano steve at pearwood.info
Wed Oct 7 23:58:11 CEST 2009

On Thu, 8 Oct 2009 04:27:22 am MRAB wrote:

> Perhaps:
> for i in SEQ:
>      A
> elif not break:
>      C # suite_if_loop_is_not_broken
> elif pass:
>      B  # suite_if_loop_body_is_not_executed

Here's my executive summary, for those in a hurry:

-1 on any variation like "else not break" or "elif not break".

+1 on aliasing "for...else" to "for...then", with identical semantics, 
with eventual deprecation and removal of for...else some time in the 
indefinite future. (Likewise for while...else.)

-0 on introducing a clause that executes if the loop is never executed 
at all.

And here are the details:

Any variation like "else not break" or "elif not break" makes it look 
that you are testing a flag. If you think for...else is confusing 
now, I guarantee that this will be nothing compared to the confusion 
people will feel when they discover this (proposed) thing that looks 
like testing a flag but isn't. People will wonder where this break 
flag is set, and why they can't set it themselves, or even access it 
like any other object.

(Before anyone suggests that perhaps we should introduce a global 
variable called "break", and allow the caller to read/write to it 
outside of the for loop, remember that break is a statement. It would 
be too abominable for words to have break a global variable and a 
statement at the same time.)

Assuming there is consensus that for...else is confusing, my 
suggestion is to add an alias "then":

for x in seq:

The behaviour of "then" is identical to the current behaviour 
of "else", it's just another way of spelling it. Assuming consensus, 
eventually else would be deprecated and then removed.

This has the advantage of a more natural interpretation. It seems more 
natural to say:

    run the loop, then execute suite (unless there was a break)

instead of 

    run the loop, optionally break, else execute suite.

If you need to distinguish between "loop ran" and "loop didn't run at 
all", you don't need syntax for that, you can use the sentinel trick 
Ilya suggested. (You don't even need a special sentinel, just use 
None, provided you know None is not in the sequence you're iterating 
over.) But if this was so common a use-case that we needed syntax for 
it (and I don't believe it is), then I'd suggest:

for x in seq:
     suite A
     suite B
     suite C

I'm not really enamoured of "otherwise". I'd prefer to use "else" for 
the case of "the loop was never entered at all", but of course that 
is impossible given that it currently has another meaning.

Steven D'Aprano 
Operations Manager 
Cybersource Pty Ltd, ABN 13 053 904 082 
Level 1, 130-132 Stawell St, Richmond VIC 3121 
Tel: +61 3 9428 6922   Fax: +61 3 9428 6944 
Web: http://www.cybersource.com.au 

More information about the Python-ideas mailing list