[Python-Dev] Adding a conditional expression in Py3.0
ncoghlan at gmail.com
Sat Sep 24 06:59:47 CEST 2005
Terry Reedy wrote:
> During the c.l.p debate, someone counted about 100 correct uses of 'a and b
> or c' in the standard library. But one real misuse edged Guido toward
> replacing it. So I think the replacement should be as clear as reasonably
> possible and clearly an improvement.
But I think there's a difference in kind here - to *fix* Raymond's example
required a fundamental change to the structure of the line, none of which
looked as clean as the original. There is no way to get the and/or construct
to gracefully handle the case where the desired result in the 'true' case
might itself be false: either you change to using an if statement, or you use
a workaround like the ugly singleton-list approach.
That is, the following is fundamentally broken for pure imaginary numbers:
return isinstance(z, ComplexType) and z.real or z
Fixing it requires changing to either:
return (isinstance(z, ComplexType) and [z.real] or [z])
if isinstance(z, ComplexType)
This is not the case with an in-fix notation for conditional expressions - you
can fix a broken line simply by moving the relevant expressions to the correct
return isinstance(z, ComplexType) if z.real else z # Broken!
return z.real if isinstance(z, ComplexType) else z # Correct!
I see this as being in the same category of error as writing "return foo **
baz" when you really should have written "return baz ** foo" (i.e., not the
language's problem). (Random aside: it would be nice if "foo ** bar % baz"
automatically invoked the three argument form of 'pow')
> Now, can you honestly say that you would (naively) read
> return foo if bar else baz
> and be certain you knew what it meant?
Yes. I'd expect it to read like English - "Return foo if bar is true,
otherwise return baz". Whether that was was what code was *supposed* to be
doing, I couldn't assess without additional context (but that is true
regardless of the syntax).
With the prefix notation used for C's conditional operator, I simply don't
read it in the order it's written - I read "return bar ? foo : baz" as "if bar
is true then return foo, otherwise return baz". That's possible with C because
it uses punctuation - using an English keyword instead makes it significantly
harder for me to consider interpreting the construct that way (In fact, the
only way I can get my brain to accept it is by mentally replacing the "if"
with "?" and the "else" with ":").
Does it help if you think of "if <C> else" as a parameterised infix operation
for choosing between the expressions on either side?
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
More information about the Python-Dev