# For review: PEP 308 - If-then-else expression

Sat Feb 8 01:49:17 CET 2003

```> PEP: 308
> Title: If-then-else expression

-1 from me.

1) Too many people like "cute" code, as in

x = this if (x if y else z) else 1 if a > 0 else 2

(Put in parens until this is legal :)

2) debugging these things is a bear

Suppose I want to say if a 2nd order polynomial of the
form a*x**2 + b*z + c == 0 has real or imaginary roots.

print "roots are", "real" if b** 2 - 4*a*c >= 0 else "imaginary"

(People will write this -- do you want this to be the future
of Python?)

Now I want to print the descriminate as well

descr = b** 2 - 4*a*c
print "descriminate =", descr
print "roots are", "real" if descr >= 0 else "imaginary"

And now I want to say if the roots are ... duplicate (forgot
the right mathematical term)

descr = b ** 2 - 4*a*c
print "descriminate =", descr
print "roots are", "real" if descr >0 else ("duplicate" if descr == 0 else
"imaginary")

Again, people WILL use this style.  I've seen it a lot in C/C++ code.
(The justification is often, "oh, I shouldn't change the structure, since
there's
a reason/expectation for it to look like this.)

Compare this to the progression of  "..if..else" is not allowed

descr  = b** 2 - 4*a*c
if descr >= 0:
root_type = "real"
else:
root_type = "imaginary"
print "roots are", root_type

Notice that this is 1) 6 lines compared to 1 line, 2) requires coming up
with two names ('descr' and 'root_type') and 3) easy to understand

(I'll beat Alex to the punch by saying this could also be written as

descr  = b** 2 - 4*a*c
root_type = ["imaginary", "real"][descr >= 0]
print "roots are", root_type

or more tersely

print "roots are", ["imaginary", "real"][b**2-4*a*c>=0]
:)

However, modifying the code is much easier.

descr  = b** 2 - 4*a*c
if descr > 0:
root_type = "real"
elsif descr == 0:
root_type = "duplicate"
else:
root_type = "imaginary"
print "descriminate =", descr
print "roots are", root_type

which is, yes, 3 times longer than would be done with the proposed syntax,
but much easier to understand than that if/else(if/else), and easier for
non-expert
programmers to debug by simply inserting "I am here" print statements
in the different branches.

(And yes Alex, this could also be written as
descr  = b** 2 - 4*a*c
print "descriminate =", descr
print "roots are", ["imaginary", "duplicate", "real"][cmp(descr, 0.0)+1]
)

So I understand that the new syntax makes expressing certain constructs
more succinct, but I believe at the cost of ease of accessibility to
non-expert users and more difficult understanding for maintainence
programmers who need to support the code.

I believed list comprehensions would have the same problem.  This
has not turned out to be the case, that I can tell.  Part of the reason it
hasn't been a problem is that few people do
[x, y for x in list1 for y in [for z in spam] if x*y > 9.801]

This sort of comprehension is frowned on in the Python community.
And it's easy to see that this is something you might want to shy
away from.

But people will use ..if..else.. in very complex ways, because 1)
it's easier to understand (when writing it) 2) people are used to this
construct from C,  and 3) because of 2) will have less exposure to
a "that's a bad idea because it's harder for others to understand it"
philosophy expressed in the rest of Python and use previous exposure
to the "if it's got it we should use it" felt by many C coders.

Andrew
dalke at dalkescientific.com

```