Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

18 views
Skip to first unread message

holger krekel

unread,
Feb 7, 2003, 12:46:55 PM2/7/03
to
Guido van Rossum wrote:
> Given that if-then-else expressions keep being requested, I hereby put
> forward a proposal. I am neutral on acceptance of the proposal; I'd
> like the c.l.py community to accept or reject it or come up with a
> counter-proposal. Please understand that I don't have a lot of time
> to moderate the discussion; I'll just wait for the community to
> discuss the proposal and agree on some way to count votes, then count
> them.

Nice overall procedure! Although i vote against discussing voting schemes :-)
Let's call for votes at some later point next week. No need to hurry.

I suspect you know the outcome already as we all know you can't
restrain yourself from using that pesky little time machine.

> Proposal
>
> The proposed syntax is as follows:
>
> <expression1> if <condition> else <expression2>
>
> This is evaluated like this:
>
> - First, <condition> is evaluated.
>
> - If <condition> is true, <expression1> is evaluated and is the
> result of the whole thing.
>
> - If <condition> is false, <expression2> is evaluated and is the
> result of the whole thing.
>
> Note that at most one of <expression1> and <expression2> is
> evaluated.

What about a missing else clause? e.g.

<expression> if <condition>

Allowing it could be nice for stuff like

result = obj(...) if callable(obj)

Note though, that this proposal obfuscates control "flow"
(which guido already knows, of course). You can't read it
neither from "left to right" nor from "right to left".

It has happenend with list comprehensions before. But this doesn't
mean it's generally a good thing. For example consider

if obj() if callable(obj) else default:
...

where it's not immeditiately obvious what happens as
keywords loose significance. And this is just the start
of oneliners i could and would come up with :-)

hoping for some good discussions.

regards,

holger

Guido van Rossum

unread,
Feb 7, 2003, 12:14:40 PM2/7/03
to
Given that if-then-else expressions keep being requested, I hereby put
forward a proposal. I am neutral on acceptance of the proposal; I'd
like the c.l.py community to accept or reject it or come up with a
counter-proposal. Please understand that I don't have a lot of time
to moderate the discussion; I'll just wait for the community to
discuss the proposal and agree on some way to count votes, then count
them.


PEP: 308
Title: If-then-else expression
Version: $Revision: 1.1 $
Last-Modified: $Date: 2003/02/07 17:03:31 $
Author: Guido van Rossum
Status: Active
Type: Standards Track
Content-Type: text/plain
Created: 7-Feb-2003
Post-History: 7-Feb-2003


Introduction

Requests for an if-then-else ("ternary") expression keep coming up
on comp.lang.python. This PEP contains a concrete proposal of a
fairly Pythonic syntax. This is the community's one chance: if
this PEP is approved with a clear majority, it will be implemented
in Python 2.4. If not, the PEP will be augmented with a summary
of the reasons for rejection and the subject better not come up
again. While I am the author of this PEP, I am neither in favor
nor against this proposal; it is up to the community to decide.
If the community can't decide, I'll reject the PEP.


Proposal

The proposed syntax is as follows:

<expression1> if <condition> else <expression2>

This is evaluated like this:

- First, <condition> is evaluated.

- If <condition> is true, <expression1> is evaluated and is the
result of the whole thing.

- If <condition> is false, <expression2> is evaluated and is the
result of the whole thing.

Note that at most one of <expression1> and <expression2> is

evaluated. This is called a "shortcut expression"; it is similar
to the way the second operand of 'and' / 'or' is only evaluated if
the first operand is true / false.

To disambiguate this in the context of other operators, the
"if...else" part in the middle acts like a left-associative binary
operator with a priority lower than that of "or", and higher than
that of "lambda".

Examples of how this works out:

x if C else y if D else z <==> x if C else (y if D else z)
x or y if C else z <==> (x or y) if C else z
x if C else y or z <==> x if C else (y or z)
lambda: x if C else y <==> lambda: (x if C else y)
x if C else lambda: y <==> SyntaxError
x if C else y, z <==> (x if C else y), z
x, y if C else z <==> x, (y if C else z)


Alternatives

Many C-derived languages use this syntax:

<condition> ? <expression1> : <expression2>

I reject this for several reasons: the colon already has many uses
in Python (even though it would actually not be ambiguous, because
the question mark requires a matching colon); for people not used
to C-derived language, it is hard to understand.


Eric Raymond proposed a variant that doesn't have this problem:

<condition> ? <expression1> ! <expression2>

While cute, this suffers from the Perlish problem of using
arbitrary punctuation with an arbitrary meaning; and it's no
easier to understand than the ?: form.


If we could live with adding a new keyword, we could use:

if <condition> then <expression1> else <expression2>

Apart from the problem of introducing a new keyword for a minor
feature, this also suffers from ambiguity at the start of a
statement; for example:

if verbose then sys.stdout.write("hello\n") else None

could be an syntactically correct expression statement, but starts
with 'if', which makes the parser believe it is the start of an
'if' statement. To resolve this, the syntax would have to require
parentheses, which makes it uglier. However, this form has the
advantage of evaluating strictly from left to right (not that that
is a requirement for being Pythonic -- list comprehensions don't).


Copyright

This document has been placed in the public domain.



Local Variables:
mode: indented-text
indent-tabs-mode: nil
sentence-end-double-space: t
fill-column: 70
End:

--Guido van Rossum (home page: http://www.python.org/~guido/)

Pad...@linux.ie

unread,
Feb 7, 2003, 1:25:01 PM2/7/03
to
Guido van Rossum wrote:
> Given that if-then-else expressions keep being requested

I really don't see any advantage only being something
else to learn for beginners. I even don't like allowing
the following on one line: if <condition> else <expression>
which you intimate yourself I believe in page 3 in...
http://www.python.org/doc/essays/ppt/regrets/PythonRegrets.pdf

Pádraig.

Andrew Koenig

unread,
Feb 7, 2003, 1:25:24 PM2/7/03
to
holger> What about a missing else clause? e.g.

holger> <expression> if <condition>

holger> Allowing it could be nice for stuff like

holger> result = obj(...) if callable(obj)

It's supposed to be an expression that yields a value.
So your example would be equivalent to

result = (obj(...) if callable(obj))

and the question is: What is the value of (x if y) when y is false?

I can't imagine any value that would do what you want.

In other words, I don't think we need a second way of writing

if callable(obj): result = obj(...)

If you really want it, then say

result = obj(...) if callable(obj) else result

or

result = obj(...) if callable(obj) else None

or whatever else you want.

--
Andrew Koenig, a...@research.att.com, http://www.research.att.com/info/ark

Jack Diederich

unread,
Feb 7, 2003, 1:17:52 PM2/7/03
to
On Fri, Feb 07, 2003 at 06:46:55PM +0100, holger krekel wrote:
> What about a missing else clause? e.g.
>
> <expression> if <condition>

if (<condition>): <expression>

is already legal so I'm -1 for yet another way to do it

> Allowing it could be nice for stuff like

> result = obj(...) if callable(obj)

-1 as above

> Note though, that this proposal obfuscates control "flow"
> (which guido already knows, of course). You can't read it
> neither from "left to right" nor from "right to left".

a good reason for -1, another would be that perl has both
ways of doing it ;)

if-theres-only-one-way-to-do-it-I-can-read-your-code-ly

-jackdied

Ebo

unread,
Feb 7, 2003, 2:13:12 PM2/7/03
to

> Examples of how this works out:
>
> x if C else y if D else z <==> x if C else (y if D else z)
> x or y if C else z <==> (x or y) if C else z
> x if C else y or z <==> x if C else (y or z)
> lambda: x if C else y <==> lambda: (x if C else y)
> x if C else lambda: y <==> SyntaxError
> x if C else y, z <==> (x if C else y), z
> x, y if C else z <==> x, (y if C else z)
>

Hi all,


Allthough I think this form of if statements could be
useful in some cases, I seriously doubt whether Python
really _needs_ this _feature_.

Apart from this construct looks rather unpythonic.

So, unless some really good arguments come along, I'd
vote nay...


$0.02


E.

Paul Rubin

unread,
Feb 7, 2003, 2:14:00 PM2/7/03
to
Guido van Rossum <gu...@python.org> writes:
> Requests for an if-then-else ("ternary") expression keep coming up
> on comp.lang.python. This PEP contains a concrete proposal of a
> fairly Pythonic syntax. This is the community's one chance: if
> this PEP is approved with a clear majority, it will be implemented
> in Python 2.4. If not, the PEP will be augmented with a summary
> of the reasons for rejection and the subject better not come up
> again. While I am the author of this PEP, I am neither in favor
> nor against this proposal; it is up to the community to decide.
> If the community can't decide, I'll reject the PEP.

Sounds fair.

> Proposal
>
> The proposed syntax is as follows:
>
> <expression1> if <condition> else <expression2>

I have to say this sounds excessively Perlish, putting the condition
after the first expression like that.

> Many C-derived languages use this syntax:
>
> <condition> ? <expression1> : <expression2>
>
> I reject this for several reasons: the colon already has many uses
> in Python (even though it would actually not be ambiguous, because
> the question mark requires a matching colon); for people not used
> to C-derived language, it is hard to understand.

If the use of the colon is consistent with other ways Python uses
colon, then using it in conditional expressions seems ok. I
personally don't have a problem with using question mark (I don't
remember having any trouble understanding it when I first encountered
it in C) but I agree that it's not so Pythonic.

Adding a keyword doesn't seem to me like a big problem, unless it's a
keyword that will break a lot of programs (e.g. don't use "n" as a
keyword). So here's another alternative:

ifelse condition: expression1 else: expression2

or if the word "ifelse" is too ugly, we could use a different one instead,
like maybe "select".

The else clause could be chainable with elif:

ifelse cond1: exp1 elif cond2: exp2 else: exp3

Hopefully that wouldn't get used too frequently, but it does sometimes
turn out useful to have several nested ?: expressions in C programs.

In the many threads that have gone by on this subject in the past,
there's been several other good suggestions. Maybe some of those can
be dug up and posted to this thread.

Keith Jones

unread,
Feb 7, 2003, 2:18:13 PM2/7/03
to
Pad...@Linux.ie wrote:
>
> I really don't see any advantage only being something
> else to learn for beginners.

Beginners don't necessarily have to learn about it. I actually
programmed C++ for years before I learned about a ? b : c. Anyway,
python is already jam-packed with far more advanced concepts than
this.

Jamie Guinan

unread,
Feb 7, 2003, 2:49:58 PM2/7/03
to
On Fri, 07 Feb 2003 12:14:40 -0500, Guido van Rossum wrote:

> Proposal
>
> The proposed syntax is as follows:
>
> <expression1> if <condition> else <expression2>

This reminds me of an idiom from another language,

big-long-complicated-expression unless simple-test-expression;

which I really dislike because after mentally parsing the
"big-long-complicated-expression" I hit the "unless
simple-test-expression" part and I have to backtrack and think "oh,
that first thing might not happen after all". Little annoyances
like that add up, and make code harder to read. I like the fact
that Python keeps things simple and consistent, and I'm perfectly
happy to trade the conciseness offered by this proposed
syntax for the clarity of doing it "the long way",

if simple-test-expression:
big-long-complicated-expression
else:
...

> If we could live with adding a new keyword, we could use:
>
> if <condition> then <expression1> else <expression2>

That looks like "one more way to do it" for simple if/else clauses.
Python's "only one obvious way to do it" philosophy is one
of its big advantages in being easy to learn, and making
existing code easy to read and maintain. I would hate to
see it drift toward timtowtdi...

-Jamie

holger krekel

unread,
Feb 7, 2003, 2:47:09 PM2/7/03
to
Andrew Koenig wrote:
> holger> What about a missing else clause? e.g.
>
> holger> <expression> if <condition>
>
> holger> Allowing it could be nice for stuff like
>
> holger> result = obj(...) if callable(obj)
>
> It's supposed to be an expression that yields a value.
> So your example would be equivalent to
>
> result = (obj(...) if callable(obj))
>
> and the question is: What is the value of (x if y) when y is false?

sorry, i also got private mail about this. I intended
to say that

result = obj() if callable(obj)

should indeed set the result to None if the condition evalutes
to false. I don't think there is any other sensible result
other than 'None'. But of course,

result = obj() if callable(obj) else None

would be more explicit. The question is whether my suggestion
has enough use cases and is thus practical enough. I sometimes
have the equivalent of this situation:

result = obj.method(...) if someconditionalexpr(obj)
if result is None:
# either we don't have such a method or
# calling it returned None

writing it today, you'd have to say either

result = someconditionalexpr(obj) and obj.method(...) or None
if result is None:
...

which is a bit tricky to understand (and results in long lines).
Or you could write

try:
result = obj.method(...)
except AttributeError:
result = None
if result is None:
# either we don't have such a method or
# calling it returned None

or

result = getattr(obj, 'method')
if result is not None:
result = obj.method(...)
if result is None:
# either we don't have such a method or
# calling it returned None

but none of these solutions reads too well. The current
constructs are an rather 'indirect' way to express this
use case.

However, i fear that the PEP might decrease python's readability
and i am currently not leaning towards one way or the other.

regards,

holger

Roman Suzi

unread,
Feb 7, 2003, 2:55:19 PM2/7/03
to
On Fri, 7 Feb 2003, Guido van Rossum wrote:

I do not like the PEP. I'd agree on syntactic support for decision tables
(with due optimization, of course), but not for individual ?:-things,
in whatever form they are presented.

If Python had lazy execution, we could have a function:

if_(cond, expr1, expr2)

and expr1 or expr2 evaluated only after cond.

For example:

iif(x < y, ```x**y```, ```y**x```)

(where ``` mark lazily (on demand) executed things)

But this, yet again, are code the thunks Python-Dev is unhappy about :-(


-1 for the PEP 308


Sincerely yours, Roman Suzi
--
r...@onego.ru =\= My AI powered by Linux RedHat 7.3


Skip Montanaro

unread,
Feb 7, 2003, 2:56:15 PM2/7/03
to

holger> What about a missing else clause? e.g.

holger> <expression> if <condition>

holger> Allowing it could be nice for stuff like

holger> result = obj(...) if callable(obj)

If obj is not callable, what is assigned to result?

Skip

Bjorn Pettersen

unread,
Feb 7, 2003, 2:46:31 PM2/7/03
to
> From: Guido van Rossum [mailto:gu...@python.org]
>
> Given that if-then-else expressions keep being requested, I hereby put
> forward a proposal. I am neutral on acceptance of the proposal; I'd
> like the c.l.py community to accept or reject it or come up with a
> counter-proposal. Please understand that I don't have a lot of time
> to moderate the discussion; I'll just wait for the community to
> discuss the proposal and agree on some way to count votes, then count
> them.

+1 on the proposal as it stands. -1 on all variations suggested so far.

-- bjorn

Jp Calderone

unread,
Feb 7, 2003, 2:19:47 PM2/7/03
to
On Fri, Feb 07, 2003 at 07:05:01PM -0000, Harvey Thomas wrote:
> [snip]
>
> Agree with your comments.
>
> What about a built-in function?
>
> iff(<condition>, <trueresult>, falseresult) which returns <trueresult> if <condition> is true,
> otherwise returns <falseresult

Requires extra things. Consider:

if foo():
bar()
else:
baz()

Duplicating this with a function is tricky.

Jp

--
up 53 days, 23:50, 3 users, load average: 0.22, 0.25, 0.26

Dave Brueck

unread,
Feb 7, 2003, 3:45:28 PM2/7/03
to
On Fri, 7 Feb 2003, Jack Diederich wrote:

> On Fri, Feb 07, 2003 at 06:46:55PM +0100, holger krekel wrote:

> > What about a missing else clause? e.g.
> >

> > <expression> if <condition>
>
> if (<condition>): <expression>
>
> is already legal so I'm -1 for yet another way to do it

Argh! :)

Please don't vote on this unless you've followed the discussion. This is
not what the PEP is about.

-Dave

Geoff Gerrietts

unread,
Feb 7, 2003, 2:16:14 PM2/7/03
to
Maybe it's been suggested before, and it's not popular for some
reason, but I think conceiving this as an operator might be the wrong
direction to go -- we go there because C did, not because it's right.

What about ifelse(condition, then clause[, else clause])? I've seen
structures like that in several languages; it seems to answer the need
without adding new syntax.

--G.

--
Geoff Gerrietts <geoff at gerrietts dot net>
-rw-rw-rw-: permissions of the beast

Harvey Thomas

unread,
Feb 7, 2003, 2:05:01 PM2/7/03
to
Jack Diederich wrote:

> Sent: 07 February 2003 18:18
> To: pytho...@python.org
> Subject: Re: For review: PEP 308 - If-then-else expression


>
>
> On Fri, Feb 07, 2003 at 06:46:55PM +0100, holger krekel wrote:
> > What about a missing else clause? e.g.
> >
> > <expression> if <condition>
>
> if (<condition>): <expression>
>
> is already legal so I'm -1 for yet another way to do it
>

> > Allowing it could be nice for stuff like

> > result = obj(...) if callable(obj)
>

> -1 as above
>
> > Note though, that this proposal obfuscates control "flow"
> > (which guido already knows, of course). You can't read it
> > neither from "left to right" nor from "right to left".
>
> a good reason for -1, another would be that perl has both
> ways of doing it ;)
>

Agree with your comments.

What about a built-in function?

iff(<condition>, <trueresult>, falseresult) which returns <trueresult> if <condition> is true,
otherwise returns <falseresult

The flow is left to right (more or less), it's similar to constructs in other languages.

It can of course be written in Python currently in a rather horrible way.

Harvey

_____________________________________________________________________
This message has been checked for all known viruses by the MessageLabs Virus Scanning Service.

Ian Sparks

unread,
Feb 7, 2003, 2:33:19 PM2/7/03
to
>>
iff(<condition>, <trueresult>, falseresult) which returns <trueresult> if <condition> is true,
otherwise returns <falseresult
<<

MSAccess Basic had this exact construct which they called an "Inline IF".

Only difference is that it was "iif" instead of "iff"

- Ian Sparks.


Jack Diederich wrote:

Harvey

--
http://mail.python.org/mailman/listinfo/python-list

Laura Creighton

unread,
Feb 7, 2003, 2:48:40 PM2/7/03
to

Some of us _said_ adding new features was going to cause this
response.

I don't see the need, and I don't want Python to support every
feature that some people want. I want 'Learning Python' to be
a nice slim book that doesn't scare people away with 'oh, but
there is so much to learn' before they try it. And I would
rather not read realms of 'C or C++ written in Python' in my
future.

They'll get over it. Maybe they'll learn about dictionary
dispatching, or some other more interesting technique while they are
at it.

Laura

Eru

unread,
Feb 7, 2003, 3:03:45 PM2/7/03
to
Guido van Rossum <gu...@python.org> escribio:

>
> Proposal
>
> The proposed syntax is as follows:
>
> <expression1> if <condition> else <expression2>

If I may give my opinion, I don't like much that syntax. I think it
introduces too much "potential obfuscation". I think it's too perlish
to be pythonic. And if we add the "empty else" option (A if condition)
it starts getting difficult to read. I prefer that obfuscation and
oneliners keep being hard to get

>
> Alternatives
>
> Many C-derived languages use this syntax:
>
> <condition> ? <expression1> : <expression2>
>
> I reject this for several reasons: the colon already has many uses
> in Python (even though it would actually not be ambiguous, because
> the question mark requires a matching colon); for people not used
> to C-derived language, it is hard to understand.
>
>
> Eric Raymond proposed a variant that doesn't have this problem:
>
> <condition> ? <expression1> ! <expression2>

I would prefer the a?b:c way. It doesn't introduce new punctuation (which
leds to more difficulty when explaining the syntax, and remembering it).
Furthermore, I don't think it's difficult to read, though I may not be very
objective about this since I've used C for quite some time.
It's also quite compact, and somehow intuitive for most seasoned programmers,
while not strictly needed for beginners.


> While cute, this suffers from the Perlish problem of using
> arbitrary punctuation with an arbitrary meaning; and it's no
> easier to understand than the ?: form.
>

I agree with that one.

>
> If we could live with adding a new keyword, we could use:
>
> if <condition> then <expression1> else <expression2>
>

Mmm, introducing a new keyword can be a problem, and I don't think it's a good
idea in this case. Moreover, it isconfusingly similar to the 'normal' syntax;
it could led to problems like doubting when 'then' is needed and when it must
not be used.

How about

if condition : expression1 else expression2

If that's not suitable for any reason (I haven't actually thought carefully
about the side effects), I prefer the a?b:c option

--
Daniel Ripolles ( Eru )
There are only two things that smell like fish.
One of them is fish

John Roth

unread,
Feb 7, 2003, 3:16:52 PM2/7/03
to

"Guido van Rossum" <gu...@python.org> wrote in message
news:mailman.104463817...@python.org...

> Given that if-then-else expressions keep being requested, I hereby put
> forward a proposal. I am neutral on acceptance of the proposal; I'd
> like the c.l.py community to accept or reject it or come up with a
> counter-proposal. Please understand that I don't have a lot of time
> to moderate the discussion; I'll just wait for the community to
> discuss the proposal and agree on some way to count votes, then count
> them.

+1 either on this, or on a conditional function that includes lazy
evaluation.

All the other ideas seem too complex for the benefits.

John Roth

Edward C. Jones

unread,
Feb 7, 2003, 3:26:07 PM2/7/03
to
Guido van Rossum wrote:
> Given that if-then-else expressions keep being requested, I hereby put
> forward a proposal. I am neutral on acceptance of the proposal; I'd
> like the c.l.py community to accept or reject it or come up with a
> counter-proposal.

One of the nicest aspects of Python is its visual simplicity which makes
it easy to read. Baroque ornamentation is fine for buildings but not for
programming languages. I see very little need for list comprehensions,
if-then-else expressions, etc.

Ed Jones

Dan Schmidt

unread,
Feb 7, 2003, 3:00:30 PM2/7/03
to
I am so keen on having a ternary operator in Python that I would
probably vote yes on any proposal that was made.

I dislike

if test:
x = a
else:
x = b

not because it is longer than

x = a if test else b

but because I think the intent of the code is much more clear if one
says "x is the result of this computation depending on test" than if
one says "if test is true, evaluate this body of code, otherwise
evaluate this other body, and by the way they both happen to assign a
value to x." My appreciation for the former comes partly from using
languages like Lisp, where there is no distinction between statements
and expressions, and partly from using functional languages, where
you really do have to decide what x is going to be all in one fell
swoop. I find that putting the logic for computing x in one place
leads to fewer errors (for one thing, you don't have to type 'x'
twice).

OK, so I would probably vote 'yes' on almost any proposal, but seriously,
this one seems fine to me. The order of operands seemed weird at first,
but I kind of like the fact that when you're reading the code, "a if
test else b" reads like a noun, because the first thing you encounter
is 'a' rather than the test. That is much more 'Englishy' to me than
encountering the condition first.

I don't worry so much about the way this can be abused by putting in
the middle of other expressions as in Guido's examples. There are
plenty of language constructs that you can abuse if you try hard
enough, even in Python.

Dan

--
http://www.dfan.org

Andrew Koenig

unread,
Feb 7, 2003, 3:16:18 PM2/7/03
to
Jamie> Little annoyances like that add up, and make code harder to
Jamie> read. I like the fact that Python keeps things simple and
Jamie> consistent, and I'm perfectly happy to trade the conciseness
Jamie> offered by this proposed syntax for the clarity of doing it
Jamie> "the long way",

Jamie> if simple-test-expression:
Jamie> big-long-complicated-expression
Jamie> else:
Jamie> ...

The trouble is that there are contexts, such as function arguments,
in which one would like to use this form but it's not allowed.

For example, suppose ints is a list of numbers, and we want to
create a list of strings each of which represents the value of
the corresponding number, except that if the number is negative,
we would like the string to be "?".

Some people would write something like this:

strs = []
for i in ints:
if i < 0:
strs.append("?")
else:
strs.append(str(i))

but others (including me) would like to be able to write this:

strs = [("?" if i < 0 else str(i)) for i in ints]

I find this example easier to understand than the previous one.

I think that if you like list comprehensions and lambda expressions,
you'll probably like PEP 308; if you don't, you probably won't.

Andrew Koenig

unread,
Feb 7, 2003, 3:24:03 PM2/7/03
to
Harvey> What about a built-in function?

Harvey> iff(<condition>, <trueresult>, falseresult) which returns
Harvey> <trueresult> if <condition> is true, otherwise returns
Harvey> <falseresult

If it were a function, it would have to evaluate all of its arguments.
Part of the point is that only one of the two results is evaluated.

Gerrit Holl

unread,
Feb 7, 2003, 3:22:15 PM2/7/03
to
Guido van Rossum schreef op vrijdag 7 februari om 18:16:27 +0000:

> x if C else y if D else z <==> x if C else (y if D else z)

Does this equal the following?

if C: x
elif D: y
else: z

> x or y if C else z <==> (x or y) if C else z
> x if C else y or z <==> x if C else (y or z)
> lambda: x if C else y <==> lambda: (x if C else y)
> x if C else lambda: y <==> SyntaxError
> x if C else y, z <==> (x if C else y), z
> x, y if C else z <==> x, (y if C else z)

I really oppose this one.
IMHO, if-else clauses should never be expressions.
IMHO, this is bad for readability.
IMHO, it is not explicit.
IMHO, it's not useful.
IMHO, it unnecceraly enlarges the language.
IMHO, it's perlish.
IMHO, it's hard to understand.
IMHO, conditions should be before resulting expressions.
IMHO, we do not need this at all.
IMHO, since else is obliged, 'x if a' is not allowed but 'x if a else None'
is, which is not intuitive.

-1

> <condition> ? <expression1> : <expression2>

> I reject this for several reasons: the colon already has many uses
> in Python (even though it would actually not be ambiguous, because
> the question mark requires a matching colon); for people not used
> to C-derived language, it is hard to understand.

I would prefer this one to the 'x-if-a-else-b'-variant, but would
still vote -1. I disagree that it's hard to understand for people
not used to a C-derived language, at least it is not true for me
(and Python was my first serious language). But we don't need it.

> if <condition> then <expression1> else <expression2>

Argh, no. Then sucks. -1

For what it's worth.

yours,
Gerrit.

--
Asperger Syndroom - een persoonlijke benadering:
http://people.nl.linux.org/~gerrit/
Het zijn tijden om je zelf met politiek te bemoeien:
http://www.sp.nl/

holger krekel

unread,
Feb 7, 2003, 3:07:19 PM2/7/03
to
Skip Montanaro wrote:
>
> holger> What about a missing else clause? e.g.
>
> holger> <expression> if <condition>
>
> holger> Allowing it could be nice for stuff like
>
> holger> result = obj(...) if callable(obj)
>
> If obj is not callable, what is assigned to result?

forget to mention: None

sorry for beeing unclear. See my other post for more
on this but note that i am not particularly in favour
of anything regarding the PEP, yet. IOW i don't
strongly advocate an optional 'else' but thought
it's worth thinking about it.

holger

Gerrit Holl

unread,
Feb 7, 2003, 3:42:45 PM2/7/03
to
Andrew Koenig schreef op vrijdag 7 februari om 21:32:24 +0000:

> I think that if you like list comprehensions and lambda expressions,
> you'll probably like PEP 308; if you don't, you probably won't.

I couldn't disagree more. I think list comprehensions and lambda's are
about opposites. Since list comprehensions are in the language, I'm very
glad I have been able to get rid of those horrible lambda's. And I have
already become addicted to list comprehensions. But I am strongly
against PEP-308, see my other post.

Skip Montanaro

unread,
Feb 7, 2003, 3:32:14 PM2/7/03
to

Geoff> What about ifelse(condition, then clause[, else clause])?

In every discussion of a ternary operator this sort of suggestion comes up.
The problem with a new builtin is that all arguments must be evaluated
before the function is called. This prevents the short-circuit behavior
that is so useful in many instances.

I've updated PEP 308 to reflect this.

Skip

Gerrit Holl

unread,
Feb 7, 2003, 3:48:36 PM2/7/03
to
Guido van Rossum schreef op vrijdag 7 februari om 18:16:27 +0000:
> x if C else y if D else z <==> x if C else (y if D else z)

Doesn't this equal ((z ,y)[bool(D)], x)[bool(C)]? I think it's
good enough.

Andrew Koenig

unread,
Feb 7, 2003, 3:57:50 PM2/7/03
to
Guido> Given that if-then-else expressions keep being requested, I
Guido> hereby put forward a proposal.

+0.8 on the proposal as it stands.

The reason for +0.8 and not +1 is that I would prefer a syntax
that doesn't evaluate right-to-left if someone can think of one.
However, list comprehensions already have similar anomalies
and they don't seem particularly bothersome.


I think this proposal is important because it significantly expands
what one can do straightforwardly in the functional domain. That is,
I consider it to be in the same general category as lambda and list
comprehensions -- features that not everyone will use, but that are
important to the people who use them.

My evidence that it is important is that (a) people keep asking for
it; (b) people keep thinking up circumlocutions to accomplish the
same thing; and (c) those circumlocutions are often either wrong
or hard to understand or remember.

Dan Schmidt

unread,
Feb 7, 2003, 3:41:07 PM2/7/03
to
Eru <ripo...@LALALAaditel.org> writes:

| Guido van Rossum <gu...@python.org> escribio:
| >
| > Proposal
| >
| > The proposed syntax is as follows:
| >
| > <expression1> if <condition> else <expression2>
|
| If I may give my opinion, I don't like much that syntax. I think it
| introduces too much "potential obfuscation". I think it's too perlish
| to be pythonic. And if we add the "empty else" option (A if condition)
| it starts getting difficult to read.

What would '(A if condition)' evaluate to if condition is false? None?
I assume that the else is required, just as you can't say
(condition ? A) in C.

| I would prefer the a?b:c way. It doesn't introduce new punctuation (which
| leds to more difficulty when explaining the syntax, and remembering
| it).

The question mark would be new punctuation, wouldn't it?

Dan

--
http://www.dfan.org

Sean Ross

unread,
Feb 7, 2003, 4:33:53 PM2/7/03
to
>
> The proposed syntax is as follows:
>
> <expression1> if <condition> else <expression2>
>

While I do not think this is necessary, I would like to offer an alternative
syntax:

<expression1> when <condition> else <expression2>

The only benefit I can see to this alternative syntax is that it will be
less likely to be confused with the existing syntax for if/elif/else, which
is probably a good thing. Although adding a keyword is often a bad thing...


>
> x if C else y if D else z <==> x if C else (y if D else z)

> x or y if C else z <==> (x or y) if C else z
> x if C else y or z <==> x if C else (y or z)
> lambda: x if C else y <==> lambda: (x if C else y)
> x if C else lambda: y <==> SyntaxError
> x if C else y, z <==> (x if C else y), z
> x, y if C else z <==> x, (y if C else z)
>

consider:

x when C else y when D else z <==> x when C else (y when D else z)
x or y when C else z <==> (x or y) when C else z
x when C else y or z <==> x when C else (y or z)
lambda: x when C else y <==> lambda: (x when C else y)
x when C else lambda: y <==> SyntaxError
x when C else y, z <==> (x when C else y), z
x, y when C else z <==> x, (y when C else z)

and, in particular:

if x when C else y:
pass

as opposed to:

if x if C else y:
pass

Just a thought,
Sean Ross


Alex Martelli

unread,
Feb 7, 2003, 4:40:52 PM2/7/03
to
Andrew Koenig wrote:
...

> For example, suppose ints is a list of numbers, and we want to
> create a list of strings each of which represents the value of
> the corresponding number, except that if the number is negative,
> we would like the string to be "?".
>
> Some people would write something like this:
>
> strs = []
> for i in ints:
> if i < 0:
> strs.append("?")
> else:
> strs.append(str(i))
>
> but others (including me) would like to be able to write this:
>
> strs = [("?" if i < 0 else str(i)) for i in ints]
>
> I find this example easier to understand than the previous one.

Me too, but offhand it appears to me that the downsides of
the forms you can use today for this kind of need, such as:

strs = [ i < 0 and '?' or str(i) for i in ints]

or

strs = [ (str(i), '?')[i<0] for i in ints]

may not be that extreme, with respect to the proposed new form,
as to warrant the new construct. So, I'm of two minds about this.
There ARE better use cases -- where both expressions can have
side effects and can possibly be false -- but not many. Readability
is so-so either way. I dunno...


> I think that if you like list comprehensions and lambda expressions,
> you'll probably like PEP 308; if you don't, you probably won't.

That may explain it -- I love LC's and detest Python's too-limited,
hobbled lambdas, so _of course_ I'm of two minds...;-).


Alex

William

unread,
Feb 7, 2003, 4:44:46 PM2/7/03
to
What about
a = exp if cond
could it be like
a = exp if cond else None

--
William Dode - http://flibuste.net

David Eppstein

unread,
Feb 7, 2003, 4:43:41 PM2/7/03
to
In article <yu994r7f...@europa.research.att.com>,
Andrew Koenig <a...@research.att.com> wrote:

> Some people would write something like this:
>
> strs = []
> for i in ints:
> if i < 0:
> strs.append("?")
> else:
> strs.append(str(i))
>
> but others (including me) would like to be able to write this:
>
> strs = [("?" if i < 0 else str(i)) for i in ints]

For both of your versions, I'd reverse the order, since str(i) seems to
be the primary intended result and "?" a fallback for unusual cases:

strs = [(str(i) if i >= 0 else "?") for i in ints]

I haven't yet thought whether I want to vote for GvR's proposal, but
one advantage of it to me is that it does emphasize the primary result
(the if clause), and de-emphasize the logic of how you choose that
result.

So, when reading such code, you can more quickly see what type of object
you're going to get: as soon as I see "str(i) if..." I can tell that the
result will be a stringified int, except for some less-common cases
where it will likely be something else resembling that. On the other
hand, for the C syntax (or similar counterproposals in this thread), the
first thing you see is the i>=0 comparison, which I don't think is the
most important feature of the expression -- you have to read more of the
expression to have any idea what kind of value it will produce.

--
David Eppstein UC Irvine Dept. of Information & Computer Science
epps...@ics.uci.edu http://www.ics.uci.edu/~eppstein/

Andrew Koenig

unread,
Feb 7, 2003, 4:39:30 PM2/7/03
to
Gerrit> Guido van Rossum schreef op vrijdag 7 februari om 18:16:27 +0000:

>> x if C else y if D else z <==> x if C else (y if D else z)

Gerrit> Doesn't this equal ((z ,y)[bool(D)], x)[bool(C)]? I think it's
Gerrit> good enough.

No, it's not equal because your version evaluates x, y, and z in
all circumstances.

OKB (not okblacke)

unread,
Feb 7, 2003, 4:58:58 PM2/7/03
to
Guido van Rossum wrote:

> The proposed syntax is as follows:
>
> <expression1> if <condition> else <expression2>

This looks like a decent proposal to me. My vote is yes.

--
--OKB (not okblacke)
"Do not follow where the path may lead. Go, instead, where there is
no path, and leave a trail."
--author unknown

Jack Diederich

unread,
Feb 7, 2003, 4:02:35 PM2/7/03
to
On Fri, Feb 07, 2003 at 12:45:28PM -0800, Dave Brueck wrote:
> On Fri, 7 Feb 2003, Jack Diederich wrote:
> > On Fri, Feb 07, 2003 at 06:46:55PM +0100, holger krekel wrote:
> > > What about a missing else clause? e.g.
> > >
> > > <expression> if <condition>
> >
> > if (<condition>): <expression>
> >
> > is already legal so I'm -1 for yet another way to do it
>
> Argh! :)
>
> Please don't vote on this unless you've followed the discussion. This is
> not what the PEP is about.

It was a reply to your reply about the PEP, but I'll rephrase it.

I'm against extending the PEP to include <expr1> if <cond> instead of
just <expr1> if <cond> else <expr2> as the PEP states.

-jackdied


Skip Montanaro

unread,
Feb 7, 2003, 3:37:47 PM2/7/03
to

Roman> I'd agree on syntactic support for decision tables (with due
Roman> optimization, of course),

Roman,

Can you describe what form you think a decision table might take in a
programming language? I am used to thinking of them as two-dimensional
structures (google for "decision tables" and click the first link returned)
which seem fairly hard to represent in a concise, readable purely text form.

Skip

Ian Bicking

unread,
Feb 7, 2003, 4:16:25 PM2/7/03
to
On Fri, 2003-02-07 at 13:47, holger krekel wrote:
> result = obj() if callable(obj)
>
> should indeed set the result to None if the condition evalutes
> to false. I don't think there is any other sensible result
> other than 'None'. But of course,
>
> result = obj() if callable(obj) else None
>
> would be more explicit. The question is whether my suggestion
> has enough use cases and is thus practical enough.

To me (obj() if callable(obj)) makes sense without the else. It's like
a function that implicitly returns None, or the .get() method on
dictionaries (without the second argument). Though admittedly I did not
recognize this behavior when I first learned Python, and it was only
later that I started depending on None being returned implicitly.

--
Ian Bicking ia...@colorstudy.com http://colorstudy.com
4869 N. Talman Ave., Chicago, IL 60625 / 773-275-7241
"There is no flag large enough to cover the shame of
killing innocent people" -- Howard Zinn

Dave Brueck

unread,
Feb 7, 2003, 2:36:23 PM2/7/03
to
On Fri, 7 Feb 2003, Guido van Rossum wrote:

> The proposed syntax is as follows:
>
> <expression1> if <condition> else <expression2>

+1 (and I vote Aahz to be the tally-person)

Here's my 2 cents:

- I miss the conditional operator from C; used it sparingly but it sure
was handy sometimes.

- I like C's syntax but mostly because I'm used to it.

- The proposed syntax takes some getting used to but after awhile it
"reads" well.

- Hopefully books and style guides will teach that if-then-else expr abuse
is akin to naming the "self" variable something besides "self" - yeah it's
*possible*, just don't *do* it.

- It'll be nice to get some closure one way or another.

-Dave

Roman Suzi

unread,
Feb 7, 2003, 4:25:34 PM2/7/03
to

I know that. But no, I can't describe how it could be represented nicely in a
programming language. I just wanted to say that I do not care much for the
?:-like operator as it adds nothing new...

>Skip
>

Sincerely yours, Roman Suzi
--
r...@onego.ru =\= My AI powered by Linux RedHat 7.3

Bjorn Pettersen

unread,
Feb 7, 2003, 4:45:37 PM2/7/03
to
> From: Sean Ross [mailto:frobozz_...@hotmail.com]
>
> >
> > The proposed syntax is as follows:
> >
> > <expression1> if <condition> else <expression2>
> >
>
> While I do not think this is necessary, I would like to offer
> an alternative
> syntax:
>
> <expression1> when <condition> else <expression2>
[...]

> Although adding a keyword is often a bad thing...

In fact, most of the time it makes it a non-starter. FWIW, I don't think
it is significantly better than if either (sorry).

-- bjorn

Sean Ross

unread,
Feb 7, 2003, 5:11:39 PM2/7/03
to
Another alternative would be:

when <condition>, <expression1> else <expression2>

or

when <condition>: <expression1> else <expression2>

This, of course, is scarcely different from the current use of if/else,
except of course that it is a one-liner...

> x when C else y when D else z <==> x when C else (y when D else z)
> x or y when C else z <==> (x or y) when C else z
> x when C else y or z <==> x when C else (y or z)
> lambda: x when C else y <==> lambda: (x when C else y)
> x when C else lambda: y <==> SyntaxError
> x when C else y, z <==> (x when C else y), z
> x, y when C else z <==> x, (y when C else z)
>
> and, in particular:
>
> if x when C else y:
> pass
>
> as opposed to:
>
> if x if C else y:
> pass
>

when C, x else when D, y else z <==> when C, x else (when D, y else z)
when C, x or y else z <==> when C, (x or y) else z
when C, x else y or z <==> when C, x else (y or z)
lambda: when C, x else y <==> lambda: (when C, x else y)
when C, x else lambda: y <==> SyntaxError
when C, x else y, z <==> (when C, x else y), z
x, when C, y else z <==> x, (when C, y else z)

and, in particular:

if when C, x else y:
pass

as opposed to:

if x if C else y:
pass


I think maybe 'x when C else y' is better, but, I figured I'd offer the
suggestion anyway.
Sean


Jamie Guinan

unread,
Feb 7, 2003, 5:16:54 PM2/7/03
to
On Fri, 07 Feb 2003 15:16:18 -0500, Andrew Koenig wrote:

> Jamie> Little annoyances like that add up, and make code harder to
> Jamie> read. I like the fact that Python keeps things simple and Jamie>
> consistent, and I'm perfectly happy to trade the conciseness Jamie>
> offered by this proposed syntax for the clarity of doing it Jamie> "the
> long way",
>
> Jamie> if simple-test-expression: Jamie>
> big-long-complicated-expression Jamie> else: Jamie> ...
>
> The trouble is that there are contexts, such as function arguments, in
> which one would like to use this form but it's not allowed.

Ah, of course, an expression returns a value (duh). I see the motivation
better now. Still, I can imagine that it would get (ab)used in contexts
where the result was ignored, just as an alternative conditional syntax.


> For example, suppose ints is a list of numbers, and we want to create a
> list of strings each of which represents the value of the corresponding
> number, except that if the number is negative, we would like the string
> to be "?".
>
> Some people would write something like this:
>
> strs = []
> for i in ints:
> if i < 0:
> strs.append("?")
> else:
> strs.append(str(i))
>
> but others (including me) would like to be able to write this:
>
> strs = [("?" if i < 0 else str(i)) for i in ints]
>
> I find this example easier to understand than the previous one.

Yes, if you wrote it - but reading the first one takes me less
time than parsing the second one.

> I think that if you like list comprehensions and lambda expressions,
> you'll probably like PEP 308; if you don't, you probably won't.

I found lambda expressions really handy for tying object methods to
xml.parsers.expat parser functions which don't accept a "this" argument.
I liked them after that. :)

-Jamie

Sean Ross

unread,
Feb 7, 2003, 5:43:31 PM2/7/03
to
In this particular case, I'd say it's significantly better...

> if x when C else y:
> pass
>
> as opposed to:
>
> if x if C else y:
> pass

If this is to be in the language, wouldn't you rather avoid the latter case
above?
If the language adds this construct, I would argue that since python
already has
a use for if, I think it would be less confusing to have a new word for this
new syntax.

On a different front:

if C?x:y:
pass

is just nasty...

And, now that I've thought on it some more, I don't care for my other
suggestion much either:

when C, x else y

but, I'm just tossing things out there...

Sean

"Bjorn Pettersen" <BPett...@NAREX.com> wrote in message
news:mailman.1044654498...@python.org...

James Kew

unread,
Feb 7, 2003, 5:55:05 PM2/7/03
to
Guido van Rossum wrote:
> <expression1> if <condition> else <expression2>
> if <condition> then <expression1> else <expression2>

On first glance, the second feels a little cleaner -- it separates
<condition> and the two <results>, whereas the first is more of a banana
sandwich (ugh).

However, it's quite hard to judge these alone without any surrounding
context. In what context do we anticipate if-then-else being used most?

Casting them in an assignment context:

x = a if <condition> else b
x = if <condition> then a else b

makes the first suddenly seem more attractive, particularly if a is the
expected result and b is an exceptional result. The second form reads like
an if statement gone wrong -- Guido worries that this is ambigous to the
parser, but I think it's worse: it's ambigious to the reader.

> x if C else y if D else z <==> x if C else (y if D else z)

Eeek! If I saw this in code I'd have to pull up sharp and puzzle it out.
This worries me a little: readability is one of the strengths I like about
Python. That said, chained list comprehensions already have the same effect
on me.

On the subject of list comprehensions: this makes me lean towards the
if..else rather than if..then..else form. List comprehensions already use an
<expression> if <condition> form:

results = [<expression> for a in stuff if <condition>]

which is nicely similar to the proposed form. And I wonder if if/else would
be worth carrying over into list comprehensions too:

results = [<expression> for a in stuff if <condition> else <expression>]

although I can't think of any non-contrived examples. And my brain starts
hurting too much when I start imagining this with both <expressions>
themselves being if-else expressions...

I sort of like it but it also scares me silly -- it feels like a very sharp
knife to solve a fairly trivial syntactic niggle. The pre-vote discussion
period is wise: my vote is still undecided.

--
James Kew
jame...@btinternet.com


Stephen Steiner

unread,
Feb 7, 2003, 5:20:35 PM2/7/03
to

-1

Yuck. Looks inside out. Blech.

Steve


Steven D. Arnold

unread,
Feb 7, 2003, 5:32:06 PM2/7/03
to
On 2/7/03 12:14 PM, "Guido van Rossum" <gu...@python.org> wrote:

> Given that if-then-else expressions keep being requested, I hereby put
> forward a proposal.

There have been many cases where I would have used such a construct and it
annoyed me that it was not there. I vote yes.

steve
--

Steven D. Arnold

unread,
Feb 7, 2003, 5:41:38 PM2/7/03
to
On 2/7/03 3:22 PM, "Gerrit Holl" <ger...@nl.linux.org> wrote:

> IMHO, since else is obliged, 'x if a' is not allowed but 'x if a else None'
> is, which is not intuitive.

I would agree here that "else" definitely should not be obligatory. The
"else None" should be implied if the else is missing. "Explicit is better
than implicit" is, I hope, a good rule of thumb rather than an absolute
principle that trumps even intuitiveness and readability.

Still, if I had to choose between the proposal as it stands or nothing at
all, I would take the proposal as it stands.

steve
--

holger krekel

unread,
Feb 7, 2003, 5:43:39 PM2/7/03
to

But why? Your above comparisons compares apples (expressions)
and oranges (statements).

I'd appreciate it if we dicuss before voting. But maybe that's
just me - beeing a silly "old" european.

holger

Eric Stechmann

unread,
Feb 7, 2003, 5:52:50 PM2/7/03
to
I'm not sure the benefits are worth the additional complication. It might
be convenient in some circumstances, but that's not necessarily a good
reason to implement it.

We're all familiar with languages that have grown to the point where they
are ugly, hard to explain or even comprehend, and, I would assume,
difficult to implement. Python is _not_ that. It's not perfect, but it
has qualities that set it above so many others: it is simple, yet powerful
and has marvelous clarity.

Implementing concepts in the name of convenience is a slippery slope. As
someone once said, "Add little to little and soon you have a big pile."

-1

Eric

--------------------------------------------------------------------------
Eric Stechmann Direct: +1 (651) 234-1217
Resident Software Hominid Fax: +1 (651) 490-1484
Advanced Respiratory, Inc. E-mail: estec...@advresp.com
1020 West County Road F URL: www.thevest.com
St.Paul MN 55126


______________________________________________________________
Information contained in this e-mail message may be legally privileged and confidential information intended only for the use of the individual(s) named above. If the reader of this message is not the intended recipient, you are hereby notified that any use, dissemination, distribution, or copying of this e-mail is strictly prohibited. If e-mailed messages include MEDICAL RECORDS, these records ARE PRIVILEGED AND CONFIDENTIAL and may be released only upon written permission of the patient. If you have received this e-mail in error, please immediately notify the sender by telephone at 1-800-426-4224 and delete this e-mail. Thank you!
______________________________________________________________


Skip Montanaro

unread,
Feb 7, 2003, 5:57:15 PM2/7/03
to

On Fri, 7 Feb 2003, Guido van Rossum wrote:

> The proposed syntax is as follows:

> <expression1> if <condition> else <expression2>

+0 from me. For the times I've needed such a construct

<cond> and <expr1> or <expr2>

has generally been sufficient. I don't see that the new syntax adds enough
to make it worthwhile, but I can ignore it as well as the next person. I'm
definitely -1 on the chained variation with "elif".

Skip

Hans Nowak

unread,
Feb 7, 2003, 6:00:48 PM2/7/03
to
Guido van Rossum wrote:

> The proposed syntax is as follows:
>
> <expression1> if <condition> else <expression2

-1. This just "feels" wrong. First you have the first option, then the
condition, then the second option.

> Examples of how this works out:


>
> x if C else y if D else z <==> x if C else (y if D else z)

> x or y if C else z <==> (x or y) if C else z
> x if C else y or z <==> x if C else (y or z)
> lambda: x if C else y <==> lambda: (x if C else y)

> x if C else lambda: y <==> SyntaxError
> x if C else y, z <==> (x if C else y), z
> x, y if C else z <==> x, (y if C else z)

None of these seem especially readable to me. Quite the opposite.

I think the drawbacks outweigh the benefits. Let's not add this.

--
Hans (base64.decodestring('d3VybXlAZWFydGhsaW5rLm5ldA=='))
# decode for email address ;-)
The Pythonic Quarter:: http://www.awaretek.com/nowak/
Kaa:: http://www.awaretek.com/nowak/kaa.html
Soon: http://zephyrfalcon.org/

Andrew Koenig

unread,
Feb 7, 2003, 5:51:50 PM2/7/03
to
Jamie> Ah, of course, an expression returns a value (duh). I see the
Jamie> motivation better now. Still, I can imagine that it would get
Jamie> (ab)used in contexts where the result was ignored, just as an
Jamie> alternative conditional syntax.

I guess it's not much different from abusing lambda expressions
in contexts where ordinary functions would be better.

David Gausebeck

unread,
Feb 7, 2003, 6:16:53 PM2/7/03
to
>Adding a keyword doesn't seem to me like a big problem, unless it's a
>keyword that will break a lot of programs (e.g. don't use "n" as a
>keyword). So here's another alternative:
>
> ifelse condition: expression1 else: expression2
>
>or if the word "ifelse" is too ugly, we could use a different one instead,
>like maybe "select".
>
>The else clause could be chainable with elif:
>
> ifelse cond1: exp1 elif cond2: exp2 else: exp3

So this would be exactly like the normal if syntax, except it's an
expression instead of a statement. This seems like a pretty
good/clean way to handle it. Also very easy to explain.

It would also be easy to allow defaulting to None. i.e.
ifelse condition: expression1
is equivalent to
ifelse condition: expression1 else: None

I agree that it would benefit from a prettier keyword, though. I
can't think of anything particularly good... "cond" or "decode" are a
couple more possibilities, though.

-Dave

Dan Schmidt

unread,
Feb 7, 2003, 5:49:06 PM2/7/03
to
"Sean Ross" <frobozz_...@hotmail.com> writes:

| when <condition>, <expression1> else <expression2>

I thought of commas too (I thought that

expr1 if cond, else expr2

might read nicely), but it makes putting these things in sequences or
argument lists harder.

--
http://www.dfan.org

Troy Melhase

unread,
Feb 7, 2003, 6:38:40 PM2/7/03
to
> PEP: 308
> Title: If-then-else expression

-1

Others have said it better, but I'll reiterate: Python doesn't need this,
nor do any of the proposals seem Pythonic in nature.


Andrew Koenig

unread,
Feb 7, 2003, 6:28:11 PM2/7/03
to
Steven> On 2/7/03 3:22 PM, "Gerrit Holl" <ger...@nl.linux.org> wrote:
>> IMHO, since else is obliged, 'x if a' is not allowed but 'x if a else None'
>> is, which is not intuitive.

Steven> I would agree here that "else" definitely should not be
Steven> obligatory. The "else None" should be implied if the else is
Steven> missing.

But then you have to figure out the meaning of

a if b if c else d

Does it mean

(a if b) if c else d

which would be equivalent to

(a if b else None) if c else d

or does it mean

a if (b if c) else d

which would be equivalent to

a if (b if c else none) else d

This ambiguity goes away if every "if" must have a corresponding "else".

Paddy

unread,
Feb 7, 2003, 6:35:26 PM2/7/03
to Eru

Eru wrote:
> Guido van Rossum <gu...@python.org> escribio:
>
>>Proposal


>>
>> The proposed syntax is as follows:
>>
>> <expression1> if <condition> else <expression2>

Don't like the above. It doesn't 'scan right for me'.

>
> Mmm, introducing a new keyword can be a problem, and I don't think it's a good
> idea in this case. Moreover, it isconfusingly similar to the 'normal' syntax;
> it could led to problems like doubting when 'then' is needed and when it must
> not be used.
>
> How about
>
> if condition : expression1 else expression2
>
> If that's not suitable for any reason (I haven't actually thought carefully
> about the side effects), I prefer the a?b:c option
>

Damn!
Eru seems to have got the same idea as I had.

I like this as it it is very similar to the if statement and so has very little extra
baggage for newbiew to learn.

I also think that the order of condition then true expr followed by false expression
'scans right'.

I would go further and suggest that the else clause be allowed to be left out. If the
condition is false then the expression should then return None.

So an if to the right of an equals sign is the ternary operator.


Rgds, Paddy.

Donald McCarthy

unread,
Feb 7, 2003, 6:35:53 PM2/7/03
to Eru

Andrew Koenig

unread,
Feb 7, 2003, 6:31:21 PM2/7/03
to
Skip> On Fri, 7 Feb 2003, Guido van Rossum wrote:

>> The proposed syntax is as follows:
>> <expression1> if <condition> else <expression2>

Skip> +0 from me. For the times I've needed such a construct

Skip> <cond> and <expr1> or <expr2>

Skip> has generally been sufficient.

except that this construct has a subtle pitfall: If <cond> is true
and <expr1> is false, the result is <expr2> instead of <expr1>.
To get around it, you have to write something like

(<cond> and [expr1] or [expr2])[0]

which is truly obscure.

Peter Hansen

unread,
Feb 7, 2003, 6:49:23 PM2/7/03
to
Gerrit Holl wrote:
>
> Guido van Rossum schreef op vrijdag 7 februari om 18:16:27 +0000:

> > x if C else y if D else z <==> x if C else (y if D else z)
>
> Doesn't this equal ((z ,y)[bool(D)], x)[bool(C)]? I think it's
> good enough.

If I saw *either* of those in real code produced by someone in my group,
the code would immediately be rewritten. Neither is readable.

I realize Guido put together the list not as a style guide but to
show how the construct would be interpreted consistently in different
potentially ambiguous contexts. I accept that. Perhaps what the
list also shows, however, is the sort of abuse that might result.
That isn't necessarily a reason to reject the idea (massively nested
if/else statements are almost equally unreadable), but it's a concern.

-Peter

Fernando Perez

unread,
Feb 7, 2003, 6:40:42 PM2/7/03
to
Guido van Rossum wrote:

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

+1.

After being spending 95% of my programming time in python for the last year
and a half, the lack of a ternary operator is probably one of the very few
things (if not the only one) which REALLY pisses me off about the language.
I love python and proselytize it heavily, but this bothers me to no end. I
find to be an affront to competent programmers to be forced to be
over-verbose to death (if/then/else in multiple lines) or absurdly obscure
(all the and/or/[] tricks).

Pretty much everything else I initially labelled as a personal 'wart' in the
language, I soon realized was my own forcing my old ways (C/Perl) onto
python instead of learning python's own way. But this one, I just can't
shake it off.

So I for one am super-super happy to see it go in (if it does indeed). At
least I can cast my vote.

Cheers,

f.

je...@compy.attbi.com

unread,
Feb 7, 2003, 7:00:19 PM2/7/03
to
On Fri, 07 Feb 2003 12:14:40 -0500, Guido van Rossum wrote:

> Given that if-then-else expressions keep being requested, I hereby put
> forward a proposal.

I'd say this is not worth doing; the benefits don't outweigh the costs.

As someone else in the thread said, he programmed in C++ for years before
seeing ?:. From what I've seen of people using ?:, it's either so trivial
that it frankly isn't saving anyone anything (a = b ? 1 : 0), or so
complicated (nested ternary operators anyone?) that the user ought to be
stripped of their license to program.

*Because* its use is so rare, it is a frequent an impediment to understanding
code to people who have never, or only rarely, seen it before. In
addition, I find it often surprisingly challenging to follow the order of
operations in such cases if the ?: isn't enclosed by (), just because
there isn't a clear 'natural' order to evaluate expressions with ternary
operators in them.

Finally, and perhaps most controversially, ISTM that people asking for ?:
are, with perhaps a few exceptions, new users of Python who expect it to
be just like the last (or even "only") language they learned. If they want
it that bad, in my experience it's probably because they're abusing it
anyhow; most programmers go a very, very long time without using it even
in languages that have it. One of Python's strengths is its stubborn
refusal to let people hang themselves with it, unless they *really
insist*.

"-1" is the vernacular, I suppose.

Richard Jones

unread,
Feb 7, 2003, 6:33:25 PM2/7/03
to
On Sat, 8 Feb 2003 7:00 am, Dan Schmidt wrote:
> I am so keen on having a ternary operator in Python that I would
> probably vote yes on any proposal that was made.
>
> I dislike
>
> if test:
> x = a
> else:
> x = b
>
> not because it is longer than
>
> x = a if test else b
>
> but because I think the intent of the code is much more clear if one
> says "x is the result of this computation depending on test" than if
> one says "if test is true, evaluate this body of code, otherwise
> evaluate this other body, and by the way they both happen to assign a
> value to x."

-1 for precisely the same reason

"x is the result of this computation ... oh, except if this is true, otherwise
it's this"

No thanks.


Richard


Carlos Ribeiro

unread,
Feb 7, 2003, 4:37:43 PM2/7/03
to
On Friday 07 February 2003 07:05 pm, Harvey Thomas wrote:
> What about a built-in function?
>
> iff(<condition>, <trueresult>, falseresult) which returns <trueresult> if
> <condition> is true, otherwise returns <falseresult
>
> The flow is left to right (more or less), it's similar to constructs in
> other languages.


Functions evaluate their arguments at call time; in this case, it means that
<falseresult> will be evaluated even if the <condition> is true. For simple
arguments it means nothing, but what if <falseresult> is a function that
should only be evaluated if <condition> is false?

There is a workaround for this, that is to have the so-called lazy evaluation
- in this mode, the arguments will only be evaluated when needed. However,
this is not supportted in Python, and I am wondering if Guido would like to
hear about it.


Carlos Ribeiro
crib...@mail.inet.com.br

je...@compy.attbi.com

unread,
Feb 7, 2003, 7:05:11 PM2/7/03
to
On Fri, 07 Feb 2003 12:45:28 -0800, Dave Brueck wrote:
> Argh! :)
>
> Please don't vote on this unless you've followed the discussion. This is
> not what the PEP is about.
>
> -Dave

I understand what you're saying, but this is *****far***** from the first
time this has been discussed. This may be the "canonical" discussion but I
seriously doubt any truly new information will be posted.

Dan Bishop

unread,
Feb 7, 2003, 7:20:49 PM2/7/03
to
Guido van Rossum <gu...@python.org> wrote in message news:<mailman.104463817...@python.org>...

> Given that if-then-else expressions keep being requested, I hereby put
> forward a proposal. I am neutral on acceptance of the proposal; I'd
> like the c.l.py community to accept or reject it or come up with a
> counter-proposal. Please understand that I don't have a lot of time
> to moderate the discussion; I'll just wait for the community to
> discuss the proposal and agree on some way to count votes, then count
> them.
[snip]

> The proposed syntax is as follows:
>
> <expression1> if <condition> else <expression2>
[snip]
> To disambiguate this in the context of other operators, the
> "if...else" part in the middle acts like a left-associative binary
> operator with a priority lower than that of "or", and higher than
> that of "lambda".

I like the idea but hate the (imho) convoluted order of the condition
and expressions.

> Alternatives
[snip]
> If we could live with adding a new keyword, we could use:


>
> if <condition> then <expression1> else <expression2>
>

> Apart from the problem of introducing a new keyword for a minor
> feature, this also suffers from ambiguity at the start of a
> statement; for example:

In the other thread, I suggested the syntax

(if condition: expression1 else expression2) # parentheses are
required

which introduces no new keywords or punctuation, and doesn't suffer
from the ambiguity you described.

Dan Schmidt

unread,
Feb 7, 2003, 6:55:32 PM2/7/03
to
Donald McCarthy <padd...@tiscali.co.uk> writes:

| So an if to the right of an equals sign is the ternary operator.

But a large part of the time I would use a ternary operator, it
wouldn't be to the right of an equals sign, it would be in an argument
list.

Dan

--
http://www.dfan.org

damien morton

unread,
Feb 7, 2003, 7:26:23 PM2/7/03
to
Guido van Rossum <gu...@python.org> wrote in message news:<mailman.104463817...@python.org>...
> Given that if-then-else expressions keep being requested, I hereby put
> forward a proposal. I am neutral on acceptance of the proposal; I'd
> like the c.l.py community to accept or reject it or come up with a
> counter-proposal. Please understand that I don't have a lot of time
> to moderate the discussion; I'll just wait for the community to
> discuss the proposal and agree on some way to count votes, then count
> them.

+1 on adding ternary if expressions.

Prefer the "if <cond> then <expr> else <expr>" form to the "<expr> if
<cond> else <expr>" form. Could live with either.

Paul Paterson

unread,
Feb 7, 2003, 7:32:04 PM2/7/03
to
"holger krekel" <py...@devel.trillke.net> wrote in message
news:mailman.1044640102...@python.org...
>
> It has happenend with list comprehensions before. But this doesn't
> mean it's generally a good thing. For example consider
>
> if obj() if callable(obj) else default:
> ...

One of the most compelling, one-line counter arguments I've ever seen!

Paul


Andrew Dalke

unread,
Feb 7, 2003, 7:49:17 PM2/7/03
to
> 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
da...@dalkescientific.com


Ryan

unread,
Feb 7, 2003, 7:47:50 PM2/7/03
to
A terinary ... , in Python.
If anyone has a real __NEED__ for this, they can code it in as a
function for their own use.
Something small involving eval probably. Just name it select or
choice.
I don't have any impetius to write in an example, but if pressed I
will :D
It doesn't deserve anything being added into the VM (parser really,
I'm guessing, but I haven't looked at the internals to check how it is
implemented, it just works)
One of the best things about Python is the readability, people that
only know higher languages don't have a real need to remember some
obscure corner case thing when they are refactoring code, just
because reading an if-else-then is easy for someone with a C
background. Even worse, all the C programmers may start using it
constantly and begin obfuscating their code for the non-C people (and
the people that don't want to parse out nested terinary operations).

In short the gain; (a minor conviniance, and a smidge more code on the
screen),
does __NOT__ mitigate the loss; (time Guido code be writing productive
code instead of fighting with the parser, possible bugs introduced by
said fighting, and possible code obfuscation).

There is no real reason for something this inane and minor being add,
also, as a minor note:
This would affect all of the different Python ports for compatability
(such as it is) on Jython, Pippy, Stackless, Vyper, ObjPy, etc...

If anyone has an enumerated list of reasons that address all of these
issues I would be glad to hear them, but I don't see any reasonable
gain from this.

srart____remove_this_underlined_part_@operamail___.com*

Guido van Rossum <gu...@python.org> wrote in message news:<mailman.104463817...@python.org>...
> Given that if-then-else expressions keep being requested, I hereby put
> forward a proposal. I am neutral on acceptance of the proposal; I'd

> Introduction
>
> Requests for an if-then-else ("ternary") expression keep coming up
> on comp.lang.python. This PEP contains a concrete proposal of a
> fairly Pythonic syntax. This is the community's one chance: if
> this PEP is approved with a clear majority, it will be implemented
> in Python 2.4. If not, the PEP will be augmented with a summary
> of the reasons for rejection and the subject better not come up
> again. While I am the author of this PEP, I am neither in favor
> nor against this proposal; it is up to the community to decide.
> If the community can't decide, I'll reject the PEP.
>

Carel Fellinger

unread,
Feb 7, 2003, 7:28:40 PM2/7/03
to
On Fri, Feb 07, 2003 at 12:14:40PM -0500, Guido van Rossum wrote:
> Given that if-then-else expressions keep being requested, I hereby put
> forward a proposal. I am neutral on acceptance of the proposal; I'd
> like the c.l.py community to accept or reject it or come up with a
> counter-proposal. Please understand that I don't have a lot of time
> to moderate the discussion; I'll just wait for the community to
> discuss the proposal and agree on some way to count votes, then count
> them.

Whether this gets added to the language or not I'd rather leave to your
instincts as a language designer --you've been doing *fine* sofar--
then to what ever gets the majority (in what ever way) of votes this
time around. So please, dont' give us voting power!


The proposal as is looks reasonable to me, it would clean up those few
uses of (a and b or c) that I have in my code.


--
groetjes, carel

Ian Bicking

unread,
Feb 7, 2003, 7:46:36 PM2/7/03
to
On Fri, 2003-02-07 at 18:00, je...@compy.attbi.com wrote:
> Finally, and perhaps most controversially, ISTM that people asking for ?:
> are, with perhaps a few exceptions, new users of Python who expect it to
> be just like the last (or even "only") language they learned. If they want
> it that bad, in my experience it's probably because they're abusing it
> anyhow; most programmers go a very, very long time without using it even
> in languages that have it. One of Python's strengths is its stubborn
> refusal to let people hang themselves with it, unless they *really
> insist*.

This isn't true. While there certainly are people who are surprised
coming to Python that it doesn't have a ternary operator, there is also
a significant number of experienced Python programmers who would like to
have an if expression.

I and many other programmers have used ugly tricks with "and" and "or"
to achieve if-like results. In fact I believe those idioms are even
becoming more widely known over time. But everyone who uses them knows
they are *bad* idioms -- they are challenging to read, challenging to
write, and bug-prone. Yet we still do it! (even if infrequently)

So the point is: we are already hanging ourselves with Python. Because
the language can't express something people *want* to express, they work
around it with a bad hack. To me this is a very compelling reason (and
after formulating it more in my mind I feel much more strongly in favor
of this PEP). I think there is a strong empirically argument for this
enhancement.

--
Ian Bicking ia...@colorstudy.com http://colorstudy.com
4869 N. Talman Ave., Chicago, IL 60625 / 773-275-7241
"There is no flag large enough to cover the shame of
killing innocent people" -- Howard Zinn

Ian Bicking

unread,
Feb 7, 2003, 7:54:01 PM2/7/03
to
On Fri, 2003-02-07 at 17:28, Andrew Koenig wrote:
> But then you have to figure out the meaning of
>
> a if b if c else d
>
> Does it mean
>
> (a if b) if c else d
>
> which would be equivalent to
>
> (a if b else None) if c else d
>
> or does it mean
>
> a if (b if c) else d
>
> which would be equivalent to
>
> a if (b if c else none) else d

I would expect it to mean

a if (b if c else d) else None

It seems obvious to me that this is the proper interpretation. But I
can't say why, which certainly implies that else needs to be required.

Of course, personally, I would find this expression to be horrible even
without the missing else. I would never put two if's in a statement
without parenthesis to make it entirely clear how to parse it.

Paul Paterson

unread,
Feb 7, 2003, 8:23:28 PM2/7/03
to
<snip PEP>

-1 (to the x if c else y)

For me, Python's strength is in its balanced expressiveness and scaling
behaviour.

I measure expressiveness in terms of how clearly the intention behind a
piece of code can be see. When I'm writing code I want to be able to easily
translate my intention into code on the page. When I'm reading some code I
want to easily see the author's intention.

It seems to me that the current PEP favours the writing side more than the
reading side. When I write,

val = x if c then y

Then this is exactly how I am thinking when I write the code. In my head I
am saying "I want val to equal x, but only if c is true, then I'd like it to
be y". So the PEP allows for expressive writing of code.

When I read the code, I have to try a bit harder because to represent the
original intention the code I need to be thinking, "val could either be x or
y depending upon condition c". To do this I have to parse the line in
reverse.

Ok, so this isn't too hard. But now look at the scaling behaviour. As you go
to more complex expressions the writing part is fine. In my head I can
easily think "I want val to be x if c is true but then I need it to be y is
d is true otherwise it should be z". Again, this is probably how I am
thinking when I write this and the PEP let me write it very easily. I'd say
the complexity of writing has scaled linearly with the complexity of my
intention.

However, when I try to read,

val = x if c else y if d else z

I have to work a lot harder to read this than I did to write it. I think the
complexity of reading has risen out of proportion to the cmplexity of the
intent of the code. When reading I'd like to think "val = select on of x, y,
z based on c and then d".

So, because the PEP favours low complexity on the writing side rather than
on the reading side I would suspect that we would start to see obscure
(cute) coding. I think I would be tempted to do it because it is very
natural to write in this way.

I think I would be +1 if an alternative form could be found where the
complexity rose in a balanced way for writing and reading these things.

Paul


Andrew Koenig

unread,
Feb 7, 2003, 8:29:25 PM2/7/03
to
Carel> The proposal as is looks reasonable to me, it would clean up
Carel> those few uses of (a and b or c) that I have in my code.

Would you mind showing us some concrete examples? I think that
some real code examples would be quite useful to the discussion.

Andrew Koenig

unread,
Feb 7, 2003, 8:33:07 PM2/7/03
to
Ian> Of course, personally, I would find this expression to be
Ian> horrible even without the missing else. I would never put two
Ian> if's in a statement without parenthesis to make it entirely clear
Ian> how to parse it.

As long as every if has an else, no parentheses are needed.
That's one argument for a mandatory "else". Another is that
the default value of None is not obvious. For example, wouldn't
you be tempted to think that

x = if y then z

means the same as

if y:
x = z

rather than

if y:
x = z
else:
x = None

?

David Eppstein

unread,
Feb 7, 2003, 8:57:16 PM2/7/03
to
In article <ad052e5c.03020...@posting.google.com>,
dan...@yahoo.com (Dan Bishop) wrote:

> I like the idea but hate the (imho) convoluted order of the condition
> and expressions.

I on the other hand think the order is one of the better parts of the
proposal. Just because it's not the same as C, doesn't make it bad...
Try thinking about it, playing with it, before reacting so quickly.

> > Alternatives
> [snip]
> > If we could live with adding a new keyword, we could use:
> >
> > if <condition> then <expression1> else <expression2>
> >
> > Apart from the problem of introducing a new keyword for a minor
> > feature, this also suffers from ambiguity at the start of a
> > statement; for example:
>
> In the other thread, I suggested the syntax
>
> (if condition: expression1 else expression2) # parentheses are
> required

-1 on this (and on most of the alternatives other people have proposed
in this thread). In this case, my reason is that the required parens
make it too easy to confuse with tuples.

--
David Eppstein UC Irvine Dept. of Information & Computer Science
epps...@ics.uci.edu http://www.ics.uci.edu/~eppstein/

David Eppstein

unread,
Feb 7, 2003, 8:57:51 PM2/7/03
to
In article <8eY0a.2044$yn1.1...@twister.austin.rr.com>,
"Paul Paterson" <hamonlypa...@houston.rr.com> wrote:

> > if obj() if callable(obj) else default:
> > ...
>
> One of the most compelling, one-line counter arguments I've ever seen!

What, just because a notation can be abused makes it always bad?

Skip Montanaro

unread,
Feb 7, 2003, 8:02:35 PM2/7/03
to
Skip> For the times I've needed such a construct

Skip> <cond> and <expr1> or <expr2>

Skip> has generally been sufficient.

Andrew> except that this construct has a subtle pitfall: If <cond> is
Andrew> true and <expr1> is false, the result is <expr2> instead of
Andrew> <expr1>.

Well understood. It's a 90% solution, and for the other 10% where I'd have
to resort to something like

Andrew> (<cond> and [expr1] or [expr2])[0]

I punt and use an if statement.

Skip

Ian Bicking

unread,
Feb 7, 2003, 8:15:06 PM2/7/03
to
On Fri, 2003-02-07 at 18:49, Andrew Dalke wrote:
> > 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?)

Yes! That is very readable. Besides the fact I haven't thought about
the quadriatic equation in years, this was very easy to read and
understand. I use this pattern all the time:

if x:
val = y
else:
val = z

And I *hate* it. "val = y if x else z" would often be better --
especially because z is None many times, or otherwise some trivial
value. Often I don't need a temporary variable at all, and did not have
one until I started working out various corner cases.

I look at your current code:

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

And it does not look nice to me. Why do you need the root_type
variable? It's meaning can be easily inferred from the print statement
(much more easily than from the variable name), and it likely serves no
purpose after that portion of code. But reading the code you don't
*know* it doesn't serve a purpose, you don't *know* that you can forget
about it. You have to hold this variable mapping in your head while you
read the rest of the code in that scope.

Each time I look over the alternate code fragments it makes it more
clear that the inline if statement can create much more readable code.
I think it is only fair to give Python programmers the option to make
their code more readable, and trust them not to also use it to make the
code less readable. Not trusting the programmer is what C++ and Wirth's
languages do -- *that* isn't the Python way.

There are lots of Python features that can be abused. People think
there aren't because Python programmers don't abuse them. I don't think
we should overly exult Python's purity.

> But people will use ..if..else.. in very complex ways, because 1)
> it's easier to understand (when writing it)

I don't think people will do this. Reading nested inline if statements
-- just from the examples people have given -- is not easy. I don't
think writing them would be easy either. But I can imagine it happening
during maintenance, when a test may be put in with an inline if because
it means modifying the code less.

> 2) people are used to this
> construct from C,

Sometimes people do crazy things in C, but most C code doesn't overuse
?: either.

> 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.

I don't think people will make the connection -- it doesn't look very
much like the C ?:. If anything it looks like Perl. But maybe that's
not a good argument :)

Carlos Ribeiro

unread,
Feb 7, 2003, 8:22:20 PM2/7/03
to
Andrew,

I'll pick just one example...

On Saturday 08 February 2003 12:49 am, Andrew Dalke wrote:
> 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

I don't think that the code above is much clearer than the one-liner with the
ternary operator. What I see is that you may be used to sequential
programming, and so, specifying every step seems to be the "right way of
doing it" for you. In my opinion, the only thing that the code above buys you
is the ability to follow it step by step, but that does not mean it's much
clearer - only that it works a few abstraction layers below the one-liner
with the ternary operator.

In my opinion, the best thing to do right now is to wait a few days for things
to settle down. I'm sure that many people that reacted against it today will
get used to the idea fairly quickly, specially if we come up with a slightly
better idiom (this one is quite good, but some good candidates for
improvement have appeared today, and more will come).

There is always reaction to change. Sometimes we get used to the new stuff so
fast that we can't even understand why did we react first place.


Carlos Ribeiro
crib...@mail.inet.com.br

David Gausebeck

unread,
Feb 7, 2003, 9:13:30 PM2/7/03
to
>Carel> The proposal as is looks reasonable to me, it would clean up
>Carel> those few uses of (a and b or c) that I have in my code.
>
>Would you mind showing us some concrete examples? I think that
>some real code examples would be quite useful to the discussion.

The simple example I used in a previous thread is:

if is_html:
extension = "html"
else:
extension = "txt"
print "Processed %s.%s." % (filename, extension)

This could currently also be implemented as

print "Processed %s.%s." % (filename, is_html and "html" or "txt")

Per the PEP, it would be

print "Processed %s.%s." % (filename, "html" if is_html else "txt")

The alternate version that I currently like is to use essentially the
current 'if' syntax but with a different keyword, operating on
expressions instead of statements. Of course, the big problem with
this is that it would require a new keyword. If the keyword is
'when', it would look like:

print "Processed %s.%s." % (filename, when is_html: "html" else: "txt")

-Dave

Christos TZOTZIOY

unread,
Feb 7, 2003, 9:28:09 PM2/7/03
to
On Fri, 07 Feb 2003 12:14:40 -0500, rumours say that Guido van Rossum
<gu...@python.org> might have written:

> The proposed syntax is as follows:
>
> <expression1> if <condition> else <expression2>

I'm +0 on ternary expressions, however I don't like the condition in the
middle. If adding a keyword is ok, what about:

<condition> then <expression1> else <expression2>

I believe it's easy to consider 'then' as a keyword only in such a case,
like as; ie. it jumps at the end of an expression without any operators
between it and the previous expression; this way, old programs don't
break even if using 'then' as a keyword.
--
TZOTZIOY, I speak England very best,
Real email address: 'dHpvdEBzaWwtdGVjLmdy\n'.decode('base64')

Andrew Koenig

unread,
Feb 7, 2003, 9:21:40 PM2/7/03
to
Skip> Well understood. It's a 90% solution, and for the other 10%
Skip> where I'd have to resort to something like

Andrew> (<cond> and [expr1] or [expr2])[0]

Skip> I punt and use an if statement.

The contexts in which I would like to be able to use an if-expression
are precisely those, such as function arguments and lambda expressions,
where if statements aren't allowed.

Andrew Dalke

unread,
Feb 7, 2003, 9:40:52 PM2/7/03
to
Me:

> But people will use ..if..else.. in very complex ways,

After some consideration, after email from Ian Bicking, I've decided that my
position was a bit too rushed. I looked through a non-trivial chunk of the
uses of "?:" in the linux kernel and decided that that construct is not
often
misused. That suggests my worries were overblown.

I still point out that:
- the examples I gave can be written in the same number of lines
(and fewer characters) using existing Python constructs, like
print ["imaginary", "duplicate", "real"][cmp(descr, 0.0)+1]

My scan of the linux source suggests that most uses of ?: are of this
sort, eg
mode_wanted ? "en" : "dis"
could be written in Python as
["en", "dis"][mode_wanted]

and *mount_opts |= f ? SF_SETUID : SF_SETGID
as mount_opts |= [SF_SETGID, SF_SETUID][bool(f)]

and iov[1].iov_base = (param == NULL) ? padding : param
as iov[1].iov_base = param or padding

and most uses of ?: are to prevent having to create a temporary
variable, and not to save evaluating both sides of the expression.

2. I still think it's easier for people to learn how the code flow
works with if/else statements because it's easy to stick in a
print statement on the different branches.

One other thing I came up with. I'll often write

x = None
if s.find("spam"):
x = "eggs?"

I do this because it guarantees that no matter what happens in the
if statement, the 'x' will be initialized. That's handy in more complicated
if statements. Also, it saves a line ;)

Take away the newlines and replace the ": x =" with "else"

x = None if s.find("spam") else "eggs?"

and the behaviour is exactly opposite. I wonder how many
times people will make that mistake?

Andrew
da...@dalkescientific.com


Andrew Koenig

unread,
Feb 7, 2003, 9:31:05 PM2/7/03
to
Ian> I use this pattern all the time:

Ian> if x:
Ian> val = y
Ian> else:
Ian> val = z

Ian> And I *hate* it.

I don't exactly hate it, but I don't like it either ...
and the reason I don't like it is that I have to write "val"
twice. That's twice as many opportunities to get it wrong.

In effect, the problem is that the surrounding context has to
be duplicated on both sides of the if. Which means that the
argument in favor of an if-then-else expression gets stronger
as the surrounding context grows. Consider:

val = map(lambda x: <something>, y)

Now imagine that the <something> contains a conditional, such as

val = map(lambda x: str(x) if x >= 0 else "(" + str(-x) + ")", y)

It's pretty clear what this does: It generates a string representation
for the values in y, putting the negative values in parentheses rather
than putting a sign in front of them.

In order to change this to an if statement, you must either repeat
the context or introduce temporaries, such as

def f(x):
if x >= 0:
return x
else:
return "(" + str(-x) + ")"
val = map(f, y)

Examples such as this are why I say that if-then-else expressions are
particularly useful in conjunction with lambda expressions.

Andrew Koenig

unread,
Feb 7, 2003, 9:32:29 PM2/7/03
to
Carlos> I don't think that the code above is much clearer than the
Carlos> one-liner with the ternary operator.

My experience is that when people say "x is much clearer than y",
what they are really saying is often "x is more familiar than y".

Andrew Dalke

unread,
Feb 7, 2003, 9:58:10 PM2/7/03
to
David Eppstein:

> I on the other hand think the order is one of the better parts of the
> proposal. Just because it's not the same as C, doesn't make it bad...
> Try thinking about it, playing with it, before reacting so quickly.

I elsewhere (but towards the end of a longish post) pointed out
that I will frequently write

x = None
if s.find("spam") > -1:
x = "spammity spam!"

The quick rewrite of this to the ...if..else.. expression is

x = None if s.find("spam") > -1 "spammity spam!"

which is wrong and gets things exactly backwards.

I believe a few people will get it wrong because of this,
either translating to or from a if/else statement.

Andrew
da...@dalkescientific.com

Andrew Dalke

unread,
Feb 7, 2003, 10:01:44 PM2/7/03
to
David Gausebeck:

> The simple example I used in a previous thread is:
>
> if is_html:
> extension = "html"
> else:
> extension = "txt"
> print "Processed %s.%s." % (filename, extension)
>
> This could currently also be implemented as
>
> print "Processed %s.%s." % (filename, is_html and "html" or "txt")
>
> Per the PEP, it would be
>
> print "Processed %s.%s." % (filename, "html" if is_html else "txt")

This could also currently be written as

print "Processed %s.%s." % (filename, ["txt", "html"][is_html])

Andrew
da...@dalkescientific.com


Carel Fellinger

unread,
Feb 7, 2003, 9:51:30 PM2/7/03
to
On Sat, Feb 08, 2003 at 01:23:28AM +0000, Paul Paterson wrote:
...

> It seems to me that the current PEP favours the writing side more than the
> reading side. When I write,
>
> val = x if c then y
>
> Then this is exactly how I am thinking when I write the code. In my head I
> am saying "I want val to equal x, but only if c is true, then I'd like it to
> be y". So the PEP allows for expressive writing of code.
>
> When I read the code, I have to try a bit harder because to represent the
> original intention the code I need to be thinking, "val could either be x or
> y depending upon condition c". To do this I have to parse the line in
> reverse.

That's funny, the few times I was lured into using the old idiom it
was more often then not during reading:) I normally started of with an
if-statement to only replace it with an and-or expression when I found
the if-statement taking up to much of the precious screen estate.

On the other hand, I've not really been exposed to Perl, so I don't
know how hard it can be to read from right to left some of the time.
I know it took me a while for list-comprehensions to make sense and
part of that was due to getting used to the expression being upfront,
but now I find that they can help make code more readable.

Likewise i hope that such a true conditional operator will make code
a tat more readable. For one you don't have to look out for those
pesky false values in the and-part of that would be conditional
operator and-or. Besides, the intention of its use is made explicit.

--
groetjes, carel

Carlos Ribeiro

unread,
Feb 7, 2003, 9:51:17 PM2/7/03
to
On Saturday 08 February 2003 02:32 am, Andrew Koenig wrote:
> Carlos> I don't think that the code above is much clearer than the
> Carlos> one-liner with the ternary operator.
>
> My experience is that when people say "x is much clearer than y",
> what they are really saying is often "x is more familiar than y".

I fully agree with you - in fact, I think that most people that reacted today
(tonight?) against the PEP are just reacting because the new syntax is not
familiar to them, and the step-by-step evaluation is.

BTW, my background is Pascal, not C/C++; I'm not familiar with ternary
operator either, but I still think that it is a rather succint way to express
some constructs.


Carlos Ribeiro
crib...@mail.inet.com.br

François Pinard

unread,
Feb 7, 2003, 9:19:50 PM2/7/03
to
> > The proposed syntax is as follows:
> >
> > <expression1> if <condition> else <expression2>

[Paul Rubin]

> I have to say this sounds excessively Perlish, putting the condition
> after the first expression like that.

We have an important precedent in Python, in the form of list comprehension,
where `if' and `for' are appended to the expression.

While I appreciate the list comprehension feature, which might be very
useful at times, it is also far too easily abused into writings which lack
legibility. I fear a bit that PEP 308 suggestion has the same benefits and
pitfalls, that is, it might be useful at times, but also may be abused.

In Python 1.5.2, the language was kind of protective against such abuse.
Now, legibility relies more on the shoulders of the programmer and less on
the language itself. That turn having already been taken by Python, my
guess is that PEP 308 suggestion would currently fit well. My reluctance to
it comes more from some remaining nostalgia of previous Python simplicity,
and nowadays, should probably be dismissed as anachronic! :-)

--
François Pinard http://www.iro.umontreal.ca/~pinard

Andrew Koenig

unread,
Feb 7, 2003, 9:58:08 PM2/7/03
to
Andrew> My scan of the linux source suggests that most uses of ?: are of this
Andrew> sort, eg
Andrew> mode_wanted ? "en" : "dis"
Andrew> could be written in Python as
Andrew> ["en", "dis"][mode_wanted]

Yes, they could be -- but in the process of translating the code, you
inverted the condition! The original yields "en" if mode_wanted is
true, and the rewrite yields "en" if mode_wanted is false.

To me, that fact is a strong argument in favor of PEP 308 :-)

Andrew Dalke

unread,
Feb 7, 2003, 10:10:51 PM2/7/03
to
Carlos Ribeiro:

> On Saturday 08 February 2003 12:49 am, Andrew Dalke wrote:
> > 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
>
> I don't think that the code above is much clearer than the one-liner with
the
> ternary operator.

And I did point out that it could be written as a one-liner in existing
Python, as in

print "roots are", ["imaginary", "duplicate", "real"][cmp(decr, 0.0)]

BTW, I think the word I should have used is "singular" and not "duplicate."
:)

> What I see is that you may be used to sequential
> programming, and so, specifying every step seems to be the "right way of
> doing it" for you. In my opinion, the only thing that the code above buys
you
> is the ability to follow it step by step, but that does not mean it's much
> clearer - only that it works a few abstraction layers below the one-liner
> with the ternary operator.

It could be. I left the C/C++/Perl world, which had a ternary, some
5+ years ago. I remember (mis)using the ternary operator a lot. I've
become a better developer since then, and it's hard to determine now
if my misuses were because of my inexperience or because of intrinsic
tendency to misuse that operator.

As I mentioned elsewhere, I've scanned the Linux kernel for use
of the ?: operator. It isn't used all that often, and most cases can
be implemented in Python with the
[false, true][expr comparison value]
construct or with the
x = y or default_value
construct.

> In my opinion, the best thing to do right now is to wait a few days for
things
> to settle down. I'm sure that many people that reacted against it today
will
> get used to the idea fairly quickly, specially if we come up with a
slightly
> better idiom (this one is quite good, but some good candidates for
> improvement have appeared today, and more will come).

I would rather see some better examples of when people would like
to use the if/else expression. People have pointed out that it can do
short circuiting, but in the real-life uses I saw in the kernel it didn't
make a different if there was short circuiting or not.

> There is always reaction to change. Sometimes we get used to the new stuff
so
> fast that we can't even understand why did we react first place.

Indeed. Though I still recall why I reacted against list comprehensions.

Andrew
da...@dalkescientific.com


Mike Meyer

unread,
Feb 7, 2003, 10:09:49 PM2/7/03
to
Andrew Koenig <a...@research.att.com> writes:

> I think that if you like list comprehensions and lambda expressions,
> you'll probably like PEP 308; if you don't, you probably won't.

I like lambdas, and some forms of list comprehensions - because they
make the resulting code more readable.

I don't like PEP 308, because I'm not convinced that it many things
more readable. I'm sure there are cases where it does, but are there
enough of them to justify it?

Lambdas and list comprehensions both start with something that sets
them apart in the expression. Lambda's with lambda, and list
comprehensions start out looking like a list. If you took the initial
'[' off of list comprehensions, they wouldn't be nearly as readable.

While I don't object to the idea of a ternary operator per se, I find
this one objectionable. The problem is that it does magic, but you
don't know that until you've read the first expression. I think that
results in an overall lowering of the readability of the code.

I'd say no.

<mike
--
Mike Meyer <m...@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.

It is loading more messages.
0 new messages