[Python-Dev] Adding a conditional expression in Py3.0

Nick Coghlan 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])[0]

   if isinstance(z, ComplexType)
       return z.real
       return z

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 mailing list