PEP 308: A PEP Writer's Experience - CON
Michael Chermside
mcherm at destiny.com
Sat Feb 8 11:12:21 EST 2003
In late 2001, when I was young and foolish (NOTE: I still am), I
tried writing a PEP for a ternary expression. I attempted to get
a consensus on c.l.py, and then write up that consensus, and of
course I failed utterly to obtain any sort of consensus, so it
never got completed. The only thing I really accomplished was to
convince MYSELF what should be done and the reasons why. I share
that with you now in hopes that it will convince people that
we should accept PEP 308.
There are lots of arguments against having a ternary expression,
and I do not find them convincing. Here I will list the main
objections I heard last time around, and respond to each.
[1] You can already achieve the same thing with an if statement
Well, yes... that's true. And that's why any decent arguments
in favor of a ternary expression must show why it's good to
have _in addition_ to the if statement.
[2] Other workarounds exist
What workaround are you talking about? If you mean
x = condition and a or b
then it fails whenever bool(a) could be false. That's a source
of unexpected bugs. If you mean
def ternary(condition, value1, value2):
if condition:
return value1
else:
return value2
x = ternary(condition, a, b)
then it fails because it is not short-circuiting (both a and
b are evaluated regardless of condition). If you meant any
of these
x = (condition and [a] or [b])[0]
x = (condition and (lambda:a) or (lambda:b))()
def ternary(condition, f1, f2):
if condition:
return f1()
else:
return f2()
x = ternary(condition, lambda a, lambda b)
then you should be ashamed of yourself - try explaining any
one of them to a beginner. And anyway, Python is known for
its readability and clarity... tricky-to-understand workarounds
should NOT be our standard approach to anything.
[3] Better spellings exist than "val1 if condition else val2"
In doing the PEP last time, I collected numerous proposed
spellings. None were perfect -- here is each with it's
weaknesses:
[3a] condition ? val1 : val2
+ same as C, C++, and Java
- not readable (except to c/java programmers)
- uses punctuation in odd ways
- : is already overused
[3b] condition ? val1 ! val2
- still uses punctuation in odd ways
- still not readable
[3c] if condition then val1 else val2
+ readable
- probably requires new keyword (perhaps "soft" keyword)
- ambiguity with if statement could make it hard to read
- ambiguity with if statement makes it impossible for
Python's parser
[3d] if condition: val1 else: val2
- overuse of :
- ambiguity with if statement could make it hard to read
- ambiguity with if statement makes it impossible for
Python's parser
[3e] if(condition) val1: val2
- overuse of :
- () already mean grouping and tuples, that's enough!
- already meaningful in python's current syntax
[3f] val1 when condition else val2
+ reads like english
- new keyword
- condition evaluated first but is textually in middle
[3g] val1 if condition else val2
+ reads like english
- condition evaluated first but is textually in middle
If you throw out the unparsable, avoid innovative uses for
punctuation that are difficult to read, and don't want to
introduce a new keyword, you're left with [3g]. It's only
real flaw is that condition appears in the middle, but
nothing's perfect. That's why Guido's PEP 308 proposes [3g].
[4] Quit changing Python -- I liked it as a small language
If you compare the introduction of a ternary operator to
recent changes, it's a much smaller change than the
introduction of list comprehensions, or introducing generators.
It won't break any code like fixing division did. It is not
a deep and powerful change like nested scopes or new-style
classes. About the only change it's comparable to is the
introduction of boolean. Really... there's no new conceptual
overhead (not a deep or confusing idea like metaclasses) --
I understand why some might like to slow the changes to
Python, but this is not the right change to object to.
More information about the Python-list
mailing list