[Python-ideas] Is this PEP-able? for X in ListY while conditionZ:
Nick Coghlan
ncoghlan at gmail.com
Sun Jun 30 09:51:46 CEST 2013
On 30 June 2013 16:43, Andrew Barnert <abarnert at yahoo.com> wrote:
> From: Nick Coghlan <ncoghlan at gmail.com>
>
> Sent: Saturday, June 29, 2013 4:51 PM
>
>
>> On 30 June 2013 01:56, Steven D'Aprano <steve at pearwood.info> wrote:
>>> In fact, I would argue the opposite, it's not *simpler* it is *more
>> complex*
>>> because it is a special case for the if keyword:
>>>
>>> break if condition # allowed
>>> continue if condition # maybe allowed?
>>> return 'spam' if condition # probably disallowed
>>> pass if condition # what's the point?
>>> raise Exception if condition # probably disallowed
>>> x += 1 if condition # almost certainly disallowed
>>
>> People already have to learn "for/else" and "while/else".
>> Adding
>> "break if" can *only* be justified on the grounds of pairing it up
>> with those two existing else clauses to make appropriate if/else
>> pairs, as "for/break if/else" and "while/break if/else"
>> should
>> actually be easier to learn than the status quo.
>
>
> I honestly don't think it would read this way to most people; the else clause would still be confusing. Especially if it continues to means the same thing even without break if, which means as soon as you "learn" the for/break if/else rule you'll learn that it's not really true.
Hence why I said any such PEP should also propose that a dangling
"else" on a loop without a break statement should be deprecated and
eventually become a syntax error. Without a break, a loop else clause
is just pointless indentation of code that could be written in line
after the loop instead. Loop else clauses *only* make sense in
combination with break, so we should just make that official and
enforce it in the compiler. While, we should probably do that
regardless, there's no incentive to work on it without some other kind
of payoff, like the ability to terminate comprehensions early :)
> Also, if it comes at the cost of making comprehensions harder to learn and understand, I think people use (and see) comprehensions much more often than for/else.
While it does have a strong statement/expression dichotomy, Python is
still one language, not two. Any proposals that rely on adding new
expression-only keywords are dead in the water. PEP 315 has now been
explicitly rejected: the official syntax for terminating a loop early
is the existing break statement, thus any proposal for terminating a
comprehension early must also be based on break if it is to be
considered a serious suggestion rather than people just idling passing
the time on an internet mailing list (I actually don't mind that last
happening a bit here - I think it's an important part of python-ideas
serving the purpose it is designed to serve. It's just important to
learn the difference between those discussions and the proposals which
actually have some hope of surviving the vigorous critique PEPs face
on python-dev).
Any proposal to allow termination of comprehensions slots into the
same design space as PEPs like 403 (the @in pseudo-decorator) and 422
(the __init_class__ hook) - they don't add fundamentally new
capabilities to the language the way context managers or generator
delegation did, they just propose tidying up a couple of rough edges
for things that are already possible, but require structuring code in
a slightly awkward way. PEP 409 is an example of an accepted PEP that
fits into the same category - it makes it easier to generate clean
exception tracebacks when you're deliberately suppressing an inner
exception and replacing it with a different one. PEP 3129 (which added
class decorators), is another good example of a "clean up" that took
an existing concept and adjusted it slightly, rather than adding a
fundamental new capability.
A proposal to allow early termination of comprehensions has *zero*
chance of acceptance as a "major language change" PEP. It simply
doesn't have enough to offer in terms of additional expressiveness.
PEP 403 (the @in pseudo-decorator) holds the promise of addressing at
least some of the many requests over the years for multi-line lambda
support, and even *that* is on dubious ground in terms of the
additional complexity vs additional expressiveness trade-off.
There's nothing wrong with cleanup PEPs, though - they're an important
part of refactoring the language design to be a bit more
self-consistent. That's why I latched on to the idea of doing
something to clean up the known wart that is loop else clauses, and
then *expanding* that to offer early termination of comprehensions. It
may still get shot down (if Guido doesn't like it, it *will* get shot
down), but the "[x for x in y; break if x is None]" variant definitely
has a few points in its favour:
- the ";" helps it read like English and avoids ambiguity relative to
filtering clauses
- the "cannot break nested comprehensions" restriction helps limit ambiguity
- the statement form adds a new "if" to go with the confusing "else" on loops
- it can be paired with deprecation of tolerating else-without-break on loops
I think the idea of early termination of comprehensions has a *much*
better chance of getting Guido's interest if it helps make the
behaviour of else clauses on loops more comprehensible without needing
elaborate explanations like
http://python-notes.curiousefficiency.org/en/latest/python_concepts/break_else.html
That still needs a volunteer to make the sales pitch in a PEP and work
out how to implement it, though :)
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
More information about the Python-ideas
mailing list