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

Proposed PEP for a Conditional Expression

3 views
Skip to first unread message

Michael Chermside

unread,
Sep 9, 2001, 10:42:49 AM9/9/01
to pytho...@python.org
Included in this email is a PEP which I am putting together dealing with
the idea of introducing a conditional expression into Python. I would
welcome any discussion, suggestions, and/or help, sent either to this
newsgroup under this topic, or emailed to me at <pyt...@mcherm.com>.

For the sake of full disclosure, I'll also express my own opinion here
(I have tried hard to keep the PEP evenhanded). With reference to the
PEP, I find ARG_1, ARG_3, and ARG_23 unconvincing, while ARG_21, ARG_22,
and ARG_3 all make sense to me. But for me, ARG_24 is the overwhelming
point and convinces me that adding a conditional expression would be a
good idea. I prefer the syntax of SPEC_2, but am certainly open to other
ideas.

I encourage others to let me know (in a form similar to the above) what
they find convincing or not, and please suggest new arguments that I've
missed.

------------------- DRAFT PEP FOLLOWS ----------------------------------
PEP: NO-NUM-YET
Title: Creating a Short-Circuiting Conditional Expression
Version: $Revision: $
Last-Modified: $Date: $
Author: pyt...@mcherm.com (Michael Chermside)
Status: Draft
Type: Standards Track
Python-Version: 2.5
Created: NOT-CREATED-YET: dd-mmm-yyyy
Post-History:


Abstract

A Frequently Asked Question by Python newbies is "How do I do the
equivalent of C's ?: syntax?". The answers, while fairly well
documented, are imperfect or incomplete. Thus many have suggested
adding some syntax to Python for this purpose. The goal of this
PEP is to gather all of the commonly proposed options and the
arguments both pro and con. It will thus serve as a focal point
for discussion and perhaps even be eventually accepted or
rejected.


Rationale

There are quite a few arguments and rationalizations for the
various proposals. Here we will distinguish between arguments for
one syntactic form over another (which should appear in the
Specification section), and arguments for or against having a
conditional expression at all will appear here.

XXX - After further discussion, either a community consensus will
be reached, or the BDFL will be invited to make a pronouncement,
at which point that conclusion will be be given here. All of the
arguments will be retained, and comments will be added here
saying which arguments were the most influential.


ARG_1: Workarounds exist.
Here are a few workarounds. See also the Python FAQ [1], and
the cookbook [2]. First, the things that DON'T work:

WORKAROUND_1: (this fails)
> def cond(c, a, b):
> if c: return a
> else: return b
> x = cond(c, a, b)
This fails, because it does not short-circuit... the
arguments the the function are always evaluated before
the function is invoked. Thus, for instance, the
following would not work properly when a == 0:
> x = cond( a==0, DEFAULT_VAL, 100/a )

WORKAROUND_2: (this SOMETIMES works)
> x = c and a or b
Because the boolean operators short circuit, this idiom
actually works quite nicely some of the time. As long as
you are sure that a will evaluate as true, this will do
the trick. It's also more readable than the other working
solutions, although it is still quite difficult to scan
for people not familiar with the idiom. If, however, a
evaluates as false, then this fails.

WORKAROUND_3: (this is the most common idiom)
> x = (c and [a] or [b])[0]
Here we create one-element lists and index into them.
Since [a] is definitely NOT false (it's got 1 element),
the and-or syntax will succeed.

WORKAROUND_4: (lambda also works)
> x = (c and (lambda:a) or (lambda:b))()
This is equivalent to WORKAROUND_3, but most people
consider it to be slightly less readable, particularly
since conditional statements are often used in lambda
expressions, thus complicating things further.

WORKAROUND_5: (just write it out!)
> if c:
> x = a
> else:
> x = b
Of course, many people would say that just writing it out
is probably the best solution. It can be done in 4 line,
or in 2, like this:
> if c: x = a
> else: x = b
In either case, though, this is NOT an expression, so
using it may require creating a temporary variable and
splitting a formula into two lines, or replacing a lambda
expression with a named function.

ARG_2: No need to clutter language.
BECAUSE workarounds exist, it is really not necessary to
clutter the language with additional ways to express the same
thing. It is a good thing for a language to be simple, and
Python has this, although if it keeps adding new features all
the time, it will eventually lose it.

ARG_3: Not a readable syntax.
The existance of a conditional expression syntax tends to
lead programmers astray. It encourages unreadable syntax like
this:
x = c1 ? c2 ? a : b : c3 ? c4 ? d : e : f
The use of syntax like if-then-else which scans more easily
will not help with the fundamental problem here, which is
that structurally, conditional expressions are easily abused
to create unreadable code. The above would be better
expressed on multiple lines, like this:
if c1:
if c2: x = a
else: x = b
else:
if c3:
if c4: x = d
else: x = e
else: x = f
In order to encourage Python programmers to write readable
programs, we should not allow conditional expressions.

ARG_21: Simplifies lambda expressions.
Lambda expressions allow one to create an annonomous function
on the fly and, while some rail agains them, others find them
both useful and expressive. However, they do NOT allow
statements, only an expression. Thus, for instance, variables
cannot be rebound in a lambda expression, since this can only
be achieved with a statement. This is generally considered to
be a good thing. However, since conditionals cannot (without
this PEP) be easily utilized in an expression, they too are
mostly unavailable in a lambda, and this restriction is one
most lambda users would like to see lifted. Here is an
example of the sort of code that many lambda users would like
to be able to write:
inverses = map( lambda x: x==0 ? "Inf" : 1.0/x, values )

ARG_22: Makes a functional style easier.
One nice feature of the Python language is that it allows the
use of a number of different programming paradigms ranging
from simple scripting to object oriented systems. One in
particular is functional programming (or at least programming
which uses many of the same approaches as would be used in a
true functional language). Features like list comprehensions
make this paradigm particularly well supported in Python.
However, there are many places where a functional style would
be much easier if a conditional expression were available.
Here is a simple example:
tags = [ s is None ? None : '<%s>' % s for s in keys ]

ARG_23: Lots of people ask for it.
Lots of people ask for a conditional expression. Even if the
other pro arguments don't convince you, what harm is there in
settling this one? For a LONG time, we used to hear
complaints about how Python lacked "+=", "*=" and such; now
that it has them, the complaints have died to a trickle.
What's wrong with just satisfying people?

ARG_24: Clarifies intent when used for assignments.
Compare the following bits of code:
Sample 1:
x = c ? a : b
Sample 2:
if c:
x = a
else:
x = b
Sample 3:
if c:
x = a
else:
y = b
Notice how using the conditional expression in sample 1 meant
that we didn't need to write "x" twice? Now, assignment
targets are rarely complex, so we're not saving many
keystrokes by typing "x" only once, but we ARE clarifying the
intent. Sample 2 makes it appear as if we want to do
DIFFERENT THINGS depending on c, when in fact, we always want
to do the SAME thing (set x), just with different values.
Sample 3 looks quite similar to Sample 2, but the
programmer's intent is completely different.


Specification

In order to try to capture the numerous suggestions that have
been made, this section will list SEVERAL specifications, each
with an identifying name (SPEC_x). XXX - After further
discussion, one specification should be selected as "preferred".
This one should be listed first, and identified in this
paragraph.

Arguments for or against HAVING a conditional expression are
found in the Rationale section, the arguments here simply deal
with different means of


SPEC_1: Use the "C syntax".
The following production would be added to Python syntax:
expression: expression ? exprression : expression
Since "?" is not currently used in Python, this would never
be syntactically ambiguous. Sample: a = b ? c : d

PRO - [familiar to programmers]
CON - [hard to read] [not pythonic]


SPEC_2: Use "if-then-else".
The following production would be added to Python syntax:
expression: "if" expression "then" expression "else"
expression
The word "then" would become a new keyword, introduced
gracefully through the use of a __future__ statement. I am
currently unclear as to whether this syntax could ever be
ambiguous.

PRO - [readable]
CON - [new keyword]


SPEC_3: Use "if-then-else" without keyword.
The same syntax would apply as in SPEC_2, except that "then"
would not become a keyword. Instead, a special rule would
apply (much like the "as" from import) making it a
pseudo-keyword only after "if" and before the "then"
pseudo-keyword or expression ":" (which would indicate that
it was an if *statement*, not a conditional expression).

PRO - [no new keyword]
CON - [pseudo-keywords are confusing]


SPEC_4: Use "if c: a else: b".
The following production would be added to Python syntax:
expression: "if" expression ":" expression "else" ":"
expression
The famous "dangling-else" problem would NOT arise because
the "else:" part would be mandatory.

PRO - [might allow "if c1: a elif c2: b else: c"]
CON - [elif thing would re-introduce dangling else problem]


SPEC_5: Use "if(c)a:b" syntax.
The syntax "if (condition) trueval : falseval" would be used.

PRO -
CON - [syntax conflict] [too many uses for () already]
[looks like line noise]
Current syntax allows the following:
> b = 'val'
> c = 1
> if (c): b


Precedence:
Orthogonal to the syntax selection is the question of
precedence. Whichever syntax is selected, this PEP proposes
that the precedence of the conditional expression be greater
than that of lambda, and less than that of "or" (see the
precedence chart in the Reference Manual [2]. Thus, the
following:
x = a or b ? c or d : e or f
would be parsed as
x = (a or b) ? (c or d) : (e or f)
rather than
x = a or (b ? (c or d) : e) or f
or anything else, and likewise, that:
x = lambda: a ? b : c
would be parsed as
x = lambda: (a ? b : c)
rather than
x = (lambda: a) ? b : c

Short Circuiting:
Regardless of which syntax selection is made, the evaluation
of the conditional expression will be short circuiting. That
means that in the expression
x = a ? b : c
if a is true, then c will NOT be evaluated, and if a is false
then b will NOT be evaluated. This could be defended on
grounds that it is similar to the short circuiting booleans
in Python, but the REAL reason is much stronger: without
short-circuiting evaluation, most of the utility of the
conditional expression is lost!


Reference Implementation

No reference implementation has been completed as yet. In fact,
no reference implementation has been begun! The implementation is
not expected to be difficult at all, but the design decisions ARE
hard, so there's little sense starting on an implementation until
the PEP status is "Accepted". XXX - After the PEP is accepted (if
it is!) please replace this paragraph with a "help wanted!" sign
<0.1 wink>!


References

[1] Python FAQ: Is there an equivalent of C's "?:" operator?
http://www.python.org/doc/FAQ.html#4.16

[2] Python Reference Manual: Precedence chart
http://www.python.org/doc/current/ref/summary.html

[3] Python Cookbook: "conditionals" in expressions
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52310


Copyright

This document has been placed in the public domain.



Local Variables:
mode: indented-text
indent-tabs-mode: nil
End:

Alex Martelli

unread,
Sep 9, 2001, 2:00:05 PM9/9/01
to
Michael Chermside wrote:

[excellent work snipped, as I just want to snipe on one point...]

> using it may require creating a temporary variable and
> splitting a formula into two lines, or replacing a lambda
> expression with a named function.

I consider that replacing lambda forms with named functions, in Python, is
an *excellent* practice, which should be encouraged by all means necessary.
If the lack of a conditional operator does indeed encourage people to
write more local def's and fewer lambdas, then (to me) that is the "killer
argument" for not introducing conditional operators.

Maybe (it's been hotly and often debated, but never PEP'd) Python would
benefit from having some more general way to insert an unnamed code block
on the fly. But Python's lambda, as it stands, is so limited and unwieldy
that encouraging more use of it makes no sense to me. If we get more
powerful lambda-like/unnamed-block-like constructs, then the issue may go
away (I don't think such an introduction would greatly benefit Python, as
it only introduces more ways to do the same things, and the extra
complication, I think, outweighs the extra expressiveness -- but I
understand how somebody coming from Ruby, Smalltalk, or FP languages can
miss such a feature terribly), and I would then have no substantial
objection to conditionals (the pro's and con's have been well presented --
to me, apart from this lambda-related point, the weighted sum is very
slightly against introducing conditionals, but not enough to make a big
difference to me either way).

In PEP terms, I think you could summarize this tirade by
s/function./function (which some would argue is a good think, given the
current pitiful state of lambda in Python)./ and have done justice to us
all adversaries of using Python's current lambdas, while staying
even-handed (as your whole pre-PEP is so admirably) even on this side issue
of potential relevance.


Alex

Terry Reedy

unread,
Sep 9, 2001, 4:08:21 PM9/9/01
to

"Michael Chermside" <mch...@destiny.com> wrote in message
news:mailman.1000046772...@python.org...

> Included in this email is a PEP which I am putting together dealing
with
> the idea of introducing a conditional expression into Python. I
would
> welcome any discussion, suggestions, and/or help, sent either to
this
> newsgroup under this topic, or emailed to me at <pyt...@mcherm.com>.

I'll do both

> PEP, I find ARG_1, ARG_3, and ARG_23 unconvincing, while ARG_21,
ARG_22,
> and ARG_3 all make sense to me

Do you really find ARG_3 both unconvincing and sensible> or is there a
typo?

I suggest relabeling arguments A1, A2, ... (anti) and P1, P2,
...(pro).

> ------------------- DRAFT PEP
FOLLOWS ----------------------------------
> PEP: NO-NUM-YET
> Title: Creating a Short-Circuiting Conditional Expression

...
> ARG_1: Workarounds exist.

It's really hard to fairly present arguments you find 'unconvincing',
so I will help you.
(Please note: I am impressed at how well you did do, especially for
version 1.)
I'm going to split this into two anti arguments, A1 and A2, and one
pro argument, P1.

A1: Python has conditional statements for conditional assignments.


> > if c:
> > x = a
> > else:
> > x = b
> Of course, many people would say that just writing it
out
> is probably the best solution. It can be done in 4
line,
> or in 2, like this:
> > if c: x = a
> > else: x = b

P1. In either case, though, this is NOT an expression, so


> using it may require creating a temporary variable and
> splitting a formula into two lines, or replacing a
lambda
> expression with a named function.

A2: Python already has short-circuiting conditional expressions (even
if some proponents of an alternative syntax refuse to recognize them
as such by dismissing them as 'workarounds').

First, the conditional expression that DOESN'T short-circuit:


> def cond(c, a, b):
> if c: return a
> else: return b
> x = cond(c, a, b)

This fails to short-circuit because arguments to a function


are always
evaluated before the function is invoked. Thus, for instance,
the
following would not work properly when a == 0:
> x = cond( a==0, DEFAULT_VAL, 100/a )

Next, the expression that ALMOST ALWAYS short-circuits
correctly:
> x = c and a or b # or, almost equivalently
> x = (not c) and b or a
The advantage of this simple form is that it syntactically
matches
the conditional expression of C with (and,or) substituted for
(?,:).
Because the boolean operators 'and' and 'or' short circuit,
this idiom
works whenever a (or b) is certain to evaluate as true for all
values
of the variables. This is true of most (all?) realistic
examples given
by proponents of a new syntax. Examples:
> inverses = map( lambda x: x==0 and "Inf" or 1.0/x, values )
> tags = [ (s is not None and '<%s>' % s or None) for s in
keys ]

If it is possible that both a and b can evaluate to 'false',
there are clumsier
but GUARENTEED-TO-WORK forms:


> x = (c and [a] or [b])[0]

> x = (c and (a,) or (b,))[0]
These index into one-element sequences which are definitely
not false.
The tuple version is slightly faster but more awkward to type
and read.


> x = (c and (lambda:a) or (lambda:b))()

Functions are also never false. The version takes longer to
type
and may be less readable, especiaoly within an outer lambda.

In short, this PEP only proposes a new syntax and not a new
funtionality,
and the argument for the new syntax must adress why such is
worth the
accompanying costs.
..
> ARG_21: Simplifies lambda expressions.
...


> ARG_22: Makes a functional style easier.

...


> ARG_24: Clarifies intent when used for assignments.

All of these are arguments for the use of expressions rather than
statements. They all apply equally well to the existing expression
forms. They are not, in themselves, arguments for a new form.

> ARG_23: Lots of people ask for it.
> Lots of people ask for a conditional expression.

Some are ignorant of the current forms, some deny that they are what
they are, and some want something we do not currently have (a simple
form without cruft, like C's, that always works) but have not settled
on anything specific for the rest of us to consider. I hope this
'PEP' helps all three groups.

Terry J. Reedy

Marcin 'Qrczak' Kowalczyk

unread,
Sep 9, 2001, 12:17:47 PM9/9/01
to
Sun, 09 Sep 2001 09:42:49 -0500, Michael Chermside <mch...@destiny.com> pisze:

> Included in this email is a PEP which I am putting together dealing with
> the idea of introducing a conditional expression into Python. I would
> welcome any discussion, suggestions, and/or help, sent either to this
> newsgroup under this topic, or emailed to me at <pyt...@mcherm.com>.

IMHO very well done!

> I prefer the syntax of SPEC_2, but am certainly open to other ideas.

Me too.

> SPEC_4: Use "if c: a else: b".
> The following production would be added to Python syntax:
> expression: "if" expression ":" expression "else" ":"
> expression
> The famous "dangling-else" problem would NOT arise because
> the "else:" part would be mandatory.
>
> PRO - [might allow "if c1: a elif c2: b else: c"]
> CON - [elif thing would re-introduce dangling else problem]

It would not introduce dangling else. You can replace 'elif' with
'else: if', it's unambiguous.

You couldn't do that in 'if' statement without introducing an
indentation level, which is why 'elif' exists in the first place.
'if' expression doesn't use indentation so having 'elif' there is
not that important.

The fact that there is always an 'else' makes it possible to
distinguish between 'if' statement and 'if' expression if somebody
cares (there shouldn't be any need for distinguising these). The
'if' statement really looks like two statements, split before 'else',
so there is no overlap in syntax.

--
__("< Marcin Kowalczyk * qrc...@knm.org.pl http://qrczak.ids.net.pl/
\__/
^^ SYGNATURA ZASTĘPCZA
QRCZAK

Tim Peters

unread,
Sep 10, 2001, 1:29:47 AM9/10/01
to pytho...@python.org
[Michael Chermside]

> Included in this email is a PEP which I am putting together dealing with
> the idea of introducing a conditional expression into Python.

Win, lose or draw, I want to thank you for writing this PEP! It's long
overdue, and it will be good to settle this issue.

> ...


> WORKAROUND_3: (this is the most common idiom)

> > x = (c and [a] or [b])[0]

> Here we create one-element lists and index into them.
> Since [a] is definitely NOT false (it's got 1 element),
> the and-or syntax will succeed.

This is frequently suggested, but almost never used. I invented this
"idiom" for Python in the very early 90's. It was in a joke thread, about
obfuscated Python. Anyone using it in real code should be shot; I've never
used it (which is why I'm still alive to type this <wink>).

> Reference Implementation
> ...


> The implementation is not expected to be difficult at all,

Beware: mucking with the parser isn't easy, especially as there are no
3-argument infix operators now. Code generation is easy in this case, but
fiddling the grammar may be a pit.


John Roth

unread,
Sep 10, 2001, 2:29:21 AM9/10/01
to

"Michael Chermside" <mch...@destiny.com> wrote in message
news:mailman.1000046772...@python.org...
> Included in this email is a PEP which I am putting together dealing with
> the idea of introducing a conditional expression into Python. I would
> welcome any discussion, suggestions, and/or help, sent either to this
> newsgroup under this topic, or emailed to me at <pyt...@mcherm.com>.

Very nice summary of the discussion. In looking it over, I finally think
I understand why workaround 3 works. Ugly as it is, it fills what need I
have for this construct.

Part of the ugliness is that it's built on the "and" and "or" blivit. I'll
grant
you that it's a useful blivit, but it's still one of the points that tends
to
astonish the novice, and leads to arcane errors when some instance
you thought was true turns out to be false because the class implements
a __len__ function.

I have mixed feelings on the "lends itself to obfuscation" issue. Python is
probably the hardest language I know of to obfuscate because of the
forced indentation. Not that it's impossible, it just takes more work. On
the other hand, when a method goes over one screen, it's a maintainability
problem.

I also have mixed feelings on the "keep it simple" issue. Simplicity is one
of those issues with multiple valid viewpoints. For me, simplicity is an
absence of special cases. In another post, someone asked that the
.count and .index methods be made available for tuples. For me, this
is simpler than not having them: the argument that a tuple is immutable
and a list is mutable simply makes no sense - it has nothing whatever
to do with the functionality of the method, and is simply one more
arbitrary rule to keep in mind.

None of the proposed syntaxes grab me; some are worse than others,
but none of them stand out and say "right!" If pressed for a preference,
I'd go with ?:, simply because it's familiar from C.

John Roth

.


Christian Tanzer

unread,
Sep 10, 2001, 2:42:16 AM9/10/01
to Alex Martelli, pytho...@python.org

> Michael Chermside wrote:
>
> [excellent work snipped, as I just want to snipe on one point...]
>
> > using it may require creating a temporary variable and
> > splitting a formula into two lines, or replacing a lambda
> > expression with a named function.
>
> I consider that replacing lambda forms with named functions, in Python, is
> an *excellent* practice, which should be encouraged by all means necessary.
> If the lack of a conditional operator does indeed encourage people to
> write more local def's and fewer lambdas, then (to me) that is the "killer
> argument" for not introducing conditional operators.

Conditional expressions provide some nice benefits totally unrelated
to lambdas.

One example: with a trivial class, one can put expressions into format
directives, like

"Found %(number)d error%(if number == 1 : '' else : 's')s" % trivial

This doesn't look too attractive if used in a one-liner, put could be
put to very good use for substitution in bigger templates.

--
Christian Tanzer tan...@swing.co.at
Glasauergasse 32 Tel: +43 1 876 62 36
A-1130 Vienna, Austria Fax: +43 1 877 66 92


Alex Martelli

unread,
Sep 10, 2001, 4:15:16 AM9/10/01
to tan...@swing.co.at, pytho...@python.org
"Christian Tanzer" <tan...@swing.co.at> writes:
...

"""
> I consider that replacing lambda forms with named functions, in Python, is
> an *excellent* practice, which should be encouraged by all means
necessary.
> If the lack of a conditional operator does indeed encourage people to
> write more local def's and fewer lambdas, then (to me) that is the "killer
> argument" for not introducing conditional operators.

Conditional expressions provide some nice benefits totally unrelated
to lambdas.
"""

As I went on to say, I find that apart from lambda issues pluses and
minuses are finely balanced. But if adding a conditional operator
does encourage people to write more lambdas and fewer named functions,
that the "killer argument" against conditionals for me personally.

"""
One example: with a trivial class, one can put expressions into format
directives, like

"Found %(number)d error%(if number == 1 : '' else : 's')s" % trivial

This doesn't look too attractive if used in a one-liner, put could be
put to very good use for substitution in bigger templates.
"""

Definitely unattractive here -- and you don't really need to
change the Python language, adding complication to it, to get
a similar effect right now. The __getitem__ method of the
class of 'trivial' can after all perfectly well define whatever
syntax it wants (as long as it's free of ')' charachters:-)
for its 'name' argument. E.g., assuming it's OK to exclude
'@' and ':' as well, since ')' has to be excluded anyway:

class WithConditionals:

def __init__(self, globals=globals(), locals=None):
# you may capture caller's globals/locals here,
# just as you would if all that trivial did in
# its __getitem__ was an eval, but that's
# besides the current issue anyway
self.globals = globals
self.locals = locals
if self.locals is None: self.locals = {}

def __getitem__(self, name):
sel = name.split('@',1)
if len(sel)==1: return eval(name, self.globals, self.locals)
choices = sel[1].split(':')
choose = eval(sel[0], self.globals, self.locals)
if choose<0: choose=0
elif choose>=len(choices): choose=len(choices)-1
return eval(choices[choose], self.globals, self.locals)

This is slightly more general than conditionals, as I let
the selector be any integer (folding all <0 to 0, all >=N
to N-1 when there are N choices to select among), but of
course that's up to one's design tastes -- which is the
nice thing about __getitem__ using its own syntax:-).

Anyway, the sample usage of this would be something like:

neat = WithConditionals()
for number in 12,0,5,1:
print "Found %(number@'no':number)s error%(number@'':'':'s')s" % neat

with output:

D:\>python wc.py
Found 12 errors
Found no error
Found 5 errors
Found 1 error

Whether you like the syntax I've improvised or not, just
as whether you share my preference for "no error" versus
"0 errors", isn't really the point here. The point, as I
see it, is that, if and when you need special syntax in
a %-format, it's easy and preferable to design it yourself
rather than waiting for Python's own syntax to change to
accomodate you. In fact, I'd prefer a totally different
approach here, one allowing me to write, e.g.:

print "%(plur_verb number 'Found') %(plur_noun number 'error')s" % neater

with the parser in __getitem__ looking for spaces and using
them, if found, to recognize formatting keywords such as
'plur_verb' -- makes for easier parsing AND for vastly easier
i18n of messages (neater itself would of course use gettext
as needed on the meaning-carrying words such as 'error' or
'Found':-).


Alex

Gareth McCaughan

unread,
Sep 10, 2001, 4:49:51 AM9/10/01
to
Michael Chermside wrote:
[SNIP: most of an excellent proto-PEP; I've preserved only
bits I want to quibble about.]

> WORKAROUND_3: (this is the most common idiom)
> > x = (c and [a] or [b])[0]
> Here we create one-element lists and index into them.
> Since [a] is definitely NOT false (it's got 1 element),
> the and-or syntax will succeed.
>
> WORKAROUND_4: (lambda also works)
> > x = (c and (lambda:a) or (lambda:b))()
> This is equivalent to WORKAROUND_3, but most people
> consider it to be slightly less readable, particularly
> since conditional statements are often used in lambda
> expressions, thus complicating things further.

This is not equivalent to WORKAROUND_3. It doesn't do the right
thing unless nested scopes are turned on.

def f(x):
return (x==0 and (lambda:1) or (lambda:x))()

generates a SyntaxWarning when compiled and a NameError when
used, under 2.1 .

> ARG_21: Simplifies lambda expressions.
> Lambda expressions allow one to create an annonomous function

"anonymous".

> Arguments for or against HAVING a conditional expression are
> found in the Rationale section, the arguments here simply deal
> with different means of

... stopping in mid-

--
Gareth McCaughan Gareth.M...@pobox.com
.sig under construc

Bernhard Herzog

unread,
Sep 10, 2001, 6:19:11 AM9/10/01
to
Michael Chermside <mch...@destiny.com> writes:

Good summary of the arguments usually made for or agains conditional
operators!

> WORKAROUND_1: (this fails)
> > def cond(c, a, b):
> > if c: return a
> > else: return b
> > x = cond(c, a, b)
> This fails, because it does not short-circuit...

It also fails because of inconsistent indentation :)

> ARG_23: Lots of people ask for it.
> Lots of people ask for a conditional expression. Even if the
> other pro arguments don't convince you, what harm is there in
> settling this one? For a LONG time, we used to hear
> complaints about how Python lacked "+=", "*=" and such; now
> that it has them, the complaints have died to a trickle.
> What's wrong with just satisfying people?

Lots of people asking for it is a reason to write the PEP, but not
necessarily a reason to actually adopt the PEP.


> SPEC_1: Use the "C syntax".
> The following production would be added to Python syntax:
> expression: expression ? exprression : expression
> Since "?" is not currently used in Python, this would never
> be syntactically ambiguous. Sample: a = b ? c : d
>
> PRO - [familiar to programmers]

But only to programmers coming from "C-like" languages.

> SPEC_2: Use "if-then-else".
[...]

> SPEC_3: Use "if-then-else" without keyword.

[...]

These are the best spellings for this, I think.


Another way that come to mind:

<expr> if <cond> else <expr>

The order in which the condition and the braches occur is unusual for
python, but this spelling has the advantage of not needing an additional
keyword or colons.

> SPEC_4: Use "if c: a else: b".
> The following production would be added to Python syntax:
> expression: "if" expression ":" expression "else" ":"
> expression
> The famous "dangling-else" problem would NOT arise because
> the "else:" part would be mandatory.

I think this would look better without the colon after the else. I'm not
sure why though.

Bernhard

--
Intevation GmbH http://intevation.de/
Sketch http://sketch.sourceforge.net/
MapIt! http://mapit.de/

sebastien

unread,
Sep 10, 2001, 7:56:58 AM9/10/01
to
> SPEC_4: Use "if c: a else: b".
> The following production would be added to Python syntax:
> expression: "if" expression ":" expression "else" ":"
> expression
> The famous "dangling-else" problem would NOT arise because
> the "else:" part would be mandatory.
>
> PRO - [might allow "if c1: a elif c2: b else: c"]
> CON - [elif thing would re-introduce dangling else problem]

If think that this option has a killer PRO argument:
It's the syntax that anyone who already know the current if construct
in python
would try in first attempt.
That's because this syntax is the only one which is coherent with the
langage and don't introduce new concept but only extend an existing
one.

That's why I'm agree for conditionnal expression with this syntax but
absolutly against the C ternary operator syntax. The over ones are
even worst because they are subbtle fluctations of the python standard
if construct and a potential source of confussion.

Terry Reedy

unread,
Sep 10, 2001, 9:10:37 AM9/10/01
to

"Christian Tanzer" <tan...@swing.co.at> wrote in message
news:mailman.1000105331...@python.org...

>Conditional expressions provide some nice benefits totally unrelated
to lambdas.
> One example: with a trivial class, one can put expressions into
format
> directives, like
> "Found %(number)d error%(if number == 1 : '' else : 's')s" %
trivial

Python does not evaluate expressions inside strings and I do not
expect it ever will.
However, this can be rewritten today as

"Found %(number)d error%s" % (num, num != 1 and 's' or '')

Terry J. Reedy

Alex Martelli

unread,
Sep 10, 2001, 9:05:57 AM9/10/01
to
"Bernhard Herzog" <b...@intevation.de> wrote in message
news:6qvgire...@abnoba.intevation.de...
...

> > What's wrong with just satisfying people?
>
> Lots of people asking for it is a reason to write the PEP, but not
> necessarily a reason to actually adopt the PEP.

Seconded on both scores. Specifically, adding to Python all the
features that "lots of people" ask for would ensure Python's
transformation into a huge, bloated language. *THIS* is "what's
wrong with just satisfying people", as here rhetorically asked:
trying to make everybody happy will ensure nobody's happy:-).


Akex

Norman Shelley

unread,
Sep 10, 2001, 3:21:32 PM9/10/01
to
I agree that ARG_24 is THE most important point. I believe this same point is
THE most important point behind the new assignment feature, e.g.
x += 1
x *= 4
..

and the same argument is THE most important point to make for a CASE/SWITCH
statement in python.
While you're in the PEP writing mode why not create another PEP where ARG_24 is
extended and pushed for all areas where it makes sense and show where new
features have been added that fit this point.

In article <mailman.1000046772...@python.org>, Michael Chermside
says...


>
>
>For the sake of full disclosure, I'll also express my own opinion here
>(I have tried hard to keep the PEP evenhanded). With reference to the
>PEP, I find ARG_1, ARG_3, and ARG_23 unconvincing, while ARG_21, ARG_22,
>and ARG_3 all make sense to me. But for me, ARG_24 is the overwhelming
>point and convinces me that adding a conditional expression would be a
>good idea.

Norman Shelley

t...@cs.ucr.edu

unread,
Sep 11, 2001, 12:23:09 AM9/11/01
to
Bernhard Herzog <b...@intevation.de> wrote:
[...]
: Another way that come to mind:

: <expr> if <cond> else <expr>

: The order in which the condition and the braches occur is unusual for
: python, but this spelling has the advantage of not needing an additional
: keyword or colons.

I strongly favor the inclusion of a short-circuiting conditional
operator, and I think that the above syntax is probably the best
suggestion, since it closely resembles colloquial English and accepted
mathematical terminology for piecewise definitions, without
introducing new lexemes into the language. E.g., the phrase

"one if by land, two if by sea"

translates to

1 if by_lang() else 2 if by_sea() else 0

and definition

/ <exp1> if <cond1>,
| <exp2> if <cond2>,
/ <exp3> if <cond3>,
f(x) = < <exp4> if <cond4>,
\ <exp5> if <cond5>,
| <exp6> if <cond6>,
\ <exp7> otherwise

translates to

f = lambda x :
<exp1> if <cond1> else
<exp2> if <cond2> else
<exp3> if <cond3> else
<exp4> if <cond4> else
<exp5> if <cond5> else
<exp6> if <cond6> else
<exp7>

Tom Payne


t...@cs.ucr.edu

unread,
Sep 11, 2001, 12:45:28 AM9/11/01
to
Alex Martelli <al...@aleax.it> wrote:
: "Bernhard Herzog" <b...@intevation.de> wrote in message

The above non-sequitur applies equally well to every proposal that
"lots of people ask for".

Tom Payne


Tim Hammerquist

unread,
Sep 11, 2001, 1:48:44 AM9/11/01
to
Me parece que t...@cs.ucr.edu <t...@cs.ucr.edu> dijo:

> Bernhard Herzog <b...@intevation.de> wrote:
> [...]
> : Another way that come to mind:
>
> : <expr> if <cond> else <expr>
>
> : The order in which the condition and the braches occur is unusual for
> : python, but this spelling has the advantage of not needing an additional
> : keyword or colons.
>
> I strongly favor the inclusion of a short-circuiting conditional
> operator, and I think that the above syntax is probably the best
> suggestion, since it closely resembles colloquial English and accepted
> mathematical terminology for piecewise definitions, without
> introducing new lexemes into the language. E.g., the phrase
>
> "one if by land, two if by sea"
>
> translates to
>
> 1 if by_lang() else 2 if by_sea() else 0

http://www.perl.org/

[ snip ]

--
Watch my captor grow old and die.
No satisfaction. Still here.
-- Morpheus, The Sandman

Christian Tanzer

unread,
Sep 11, 2001, 3:26:22 AM9/11/01
to Alex Martelli, pytho...@python.org

"Alex Martelli" <ale...@yahoo.com> wrote:
> """
> One example: with a trivial class, one can put expressions into format
> directives, like
>
> "Found %(number)d error%(if number == 1 : '' else : 's')s" % trivial
>
> This doesn't look too attractive if used in a one-liner, put could be
> put to very good use for substitution in bigger templates.
> """
> Definitely unattractive here -- and you don't really need to
> change the Python language, adding complication to it, to get
> a similar effect right now. The __getitem__ method of the
> class of 'trivial' can after all perfectly well define whatever
> syntax it wants (as long as it's free of ')' charachters:-)
> for its 'name' argument. E.g., assuming it's OK to exclude
> '@' and ':' as well, since ')' has to be excluded anyway:

Sure, that's one of Python's strengths. I just think it's a waste if
everybody implements his own pet class to solve one specific instance
of a general problem like this.

IMHO, conditional expressions add substantial benefit if the syntax is
readable.

> In fact, I'd prefer a totally different
> approach here, one allowing me to write, e.g.:
>
> print "%(plur_verb number 'Found') %(plur_noun number 'error')s" % neater
>
> with the parser in __getitem__ looking for spaces and using
> them, if found, to recognize formatting keywords such as
> 'plur_verb' -- makes for easier parsing AND for vastly easier
> i18n of messages (neater itself would of course use gettext
> as needed on the meaning-carrying words such as 'error' or
> 'Found':-).

Well, I'd use the contents of the interpolated string as key to get
the translation (via gettext or otherwise). After all, different
languages might have totally different rules how to adapt a sentence
to the context supplied by `neater`.

Alex Martelli

unread,
Sep 11, 2001, 4:47:37 AM9/11/01
to tan...@swing.co.at, pytho...@python.org
"Christian Tanzer" <tan...@swing.co.at> writes:
...
"""
> print "%(plur_verb number 'Found') %(plur_noun number 'error')s" % neater
>
> with the parser in __getitem__ looking for spaces and using
> them, if found, to recognize formatting keywords such as
> 'plur_verb' -- makes for easier parsing AND for vastly easier
> i18n of messages (neater itself would of course use gettext
> as needed on the meaning-carrying words such as 'error' or
> 'Found':-).

Well, I'd use the contents of the interpolated string as key to get
the translation (via gettext or otherwise). After all, different
languages might have totally different rules how to adapt a sentence
to the context supplied by `neater`.
"""

In my experience that doesn't work well when the messages
include numbers that can vary all over the place, like,
here, the number of errors -- the i18n db gets overwhelmed
by almost-identical messages. Yes, working by fragments
isn't quite as satisfactory -- here, I'm forcing the
verb to come before the direct object, for example, and
that might not be ideal for some languages -- that would
need some extra tricks.


Alex

Christian Tanzer

unread,
Sep 11, 2001, 3:30:50 AM9/11/01
to pytho...@python.org

"Terry Reedy" <tjr...@home.com> wrote:

> "Christian Tanzer" <tan...@swing.co.at> wrote in message
> news:mailman.1000105331...@python.org...
>
> >Conditional expressions provide some nice benefits totally unrelated to lambdas.
> > One example: with a trivial class, one can put expressions into format
> > directives, like
> > "Found %(number)d error%(if number == 1 : '' else : 's')s" % trivial
>
> Python does not evaluate expressions inside strings and I do not
> expect it ever will.

It does already. All you need is to write a class defining an
appropriate `__getitem__` method and pass an instance thereof to the
`%` operator applied to the string in question.

> However, this can be rewritten today as
>
> "Found %(number)d error%s" % (num, num != 1 and 's' or '')

How is it that people complain that conditional expressions make for
unreadable code and then advocate obfuscations like the one above?
Besides, this style fares very badly if you ever want to go for I18N.

Alex Martelli

unread,
Sep 11, 2001, 5:47:30 AM9/11/01
to
<t...@cs.ucr.edu> wrote in message news:9nk4t8$4qq$1...@glue.ucr.edu...

Exactly, except it's not a non-sequitur. "Just satisfying people"
(by meeting every popular feature request) is NO way to design a
language (or, as it happens, any other large software system:-).


Alex

t...@cs.ucr.edu

unread,
Sep 11, 2001, 8:26:04 AM9/11/01
to
Michael Chermside <mch...@destiny.com> wrote:
[...]
: ARG_1: Workarounds exist.

: Here are a few workarounds. See also the Python FAQ [1], and
: the cookbook [2]. First, the things that DON'T work:

: WORKAROUND_1: (this fails)
: > def cond(c, a, b):
: > if c: return a
: > else: return b
: > x = cond(c, a, b)
: This fails, because it does not short-circuit... the
: arguments the the function are always evaluated before
: the function is invoked. Thus, for instance, the
: following would not work properly when a == 0:
: > x = cond( a==0, DEFAULT_VAL, 100/a )

But cond would work if it were a macro. ;-)

: WORKAROUND_2: (this SOMETIMES works)


: > x = c and a or b
: Because the boolean operators short circuit, this idiom
: actually works quite nicely some of the time. As long as
: you are sure that a will evaluate as true, this will do
: the trick. It's also more readable than the other working
: solutions, although it is still quite difficult to scan
: for people not familiar with the idiom. If, however, a
: evaluates as false, then this fails.

The problem of determining whether or not a given expression ever
evaluates to false is equivalent to determining whether a given Turing
machine halts, i.e., the general case is not algorithmically solvable.
I would like to discourage the use of constructs that introduce
unnecessary occurrences of such concerns. We need an operator that
works correctly in the general case and should then use it in the
particular case, so that readers can tell what our programs are trying
to do.

: WORKAROUND_3: (this is the most common idiom)


: > x = (c and [a] or [b])[0]
: Here we create one-element lists and index into them.
: Since [a] is definitely NOT false (it's got 1 element),
: the and-or syntax will succeed.

This hack make inefficient use of both CPU time and human patience.

: WORKAROUND_4: (lambda also works)


: > x = (c and (lambda:a) or (lambda:b))()
: This is equivalent to WORKAROUND_3, but most people
: consider it to be slightly less readable, particularly
: since conditional statements are often used in lambda
: expressions, thus complicating things further.

This doesn't work if expression a or expression b involves a local
variable.

: WORKAROUND_5: (just write it out!)


: > if c:
: > x = a
: > else:
: > x = b
: Of course, many people would say that just writing it out
: is probably the best solution. It can be done in 4 line,
: or in 2, like this:
: > if c: x = a
: > else: x = b
: In either case, though, this is NOT an expression, so
: using it may require creating a temporary variable and
: splitting a formula into two lines, or replacing a lambda
: expression with a named function.

Compared to a conditional expression this workaround pollutes the
namespace (and the reader's mind) with another name and adds two to
four additional lines of code.

FWIW, here are a couple of additional workaround candidates:

WORKAROUND_6
> c and a or not c and b
This hack involves a reevaluation of c that can be
eliminated from compiled code via common-subexpression
elimination. Also, cascading this hack gets very ugly:
<cond1> and <exp1> or
not <cond1> and <cond2> and <exp2> or
not <cond1> and not <cond2> and <cond3> and <exp3> or
<exp4>

WORKAROUND_7
> eval( c and "<expression a>" or "<expression b>" )
I don't like this hack either, but under interpretative
execution it's probably more efficient than creating
one-member lists (see WORKAROUND_3).

Tom Payne

Marcin 'Qrczak' Kowalczyk

unread,
Sep 11, 2001, 9:39:43 AM9/11/01
to
Tue, 11 Sep 2001 12:26:04 +0000 (UTC), t...@cs.ucr.edu <t...@cs.ucr.edu> pisze:

> WORKAROUND_7
> > eval( c and "<expression a>" or "<expression b>" )
> I don't like this hack either, but under interpretative
> execution it's probably more efficient than creating
> one-member lists (see WORKAROUND_3).

I don't believe.

Terry Reedy

unread,
Sep 11, 2001, 4:02:49 PM9/11/01
to

<t...@cs.ucr.edu> wrote in message news:9nkvss$cmq$1...@glue.ucr.edu...

> : WORKAROUND_2: (this SOMETIMES works)
> : > x = c and a or b

> The problem of determining whether or not a given expression ever


> evaluates to false is equivalent to determining whether a given
Turing
> machine halts, i.e., the general case is not algorithmically
solvable.

True, but so what? Most real examples seem to involve constants that
are triviallly either true or false or simple expressions that are
trivial to decide in context.

Terry J. Reedy

Gareth McCaughan

unread,
Sep 11, 2001, 6:56:06 PM9/11/01
to
Terry Reedy wrote:

[Christian Tanzer:]


> > Conditional expressions provide some nice benefits totally
> > unrelated to lambdas.
> > One example: with a trivial class, one can put expressions into
> > format directives, like
> > "Found %(number)d error%(if number == 1 : '' else : 's')s" % trivial
>
> Python does not evaluate expressions inside strings and I do not
> expect it ever will.

class Trivial:
def __getitem__(self, key):
return eval(key, globals(), locals())

"foo %(1+2+3)s bar" % Trivial() ===> "foo 6 bar"

Giving it access to the caller's local variables
isn't quite so easy.

Christian Tanzer

unread,
Sep 12, 2001, 2:52:25 AM9/12/01
to Alex Martelli, pytho...@python.org

"Alex Martelli" <ale...@yahoo.com> wrote:

Sorry for my unclear wording.

I wanted to say I would use something like (with `_` a suitable function
returning the translated text):

_("string to be interpolated containing conditional code") % context

i.e., use the template (before interpolation) -- takes just one key per
sentence and still allows all the variation necessary to support the
wide variety of grammars out there (and I know that there are more
variations than I know about <wink>). If one used such an
architecture, the conditional operators inside the templates must be
understood by the translators. So it better were readable and robust.

I cannot imagine how your proposal using `plur_noun` &c. functions
could really be made to fly -- word order varies wildly between
languages. [Disclaimer: I'm not a linguist and the only languages I
know in any detail are German and English. Besides, I don't have any
practical experience with I18N yet.]

t...@cs.ucr.edu

unread,
Sep 12, 2001, 6:56:13 AM9/12/01
to
Alex Martelli <al...@aleax.it> wrote:
: <t...@cs.ucr.edu> wrote in message news:9nk4t8$4qq$1...@glue.ucr.edu...
:> Alex Martelli <al...@aleax.it> wrote:
[...]
:> : Seconded on both scores. Specifically, adding to Python all the

:> : features that "lots of people" ask for would ensure Python's
:> : transformation into a huge, bloated language. *THIS* is "what's
:> : wrong with just satisfying people", as here rhetorically asked:
:> : trying to make everybody happy will ensure nobody's happy:-).
:>
:> The above non-sequitur applies equally well to every proposal that
:> "lots of people ask for".

: Exactly, except it's not a non-sequitur. "Just satisfying people"
: (by meeting every popular feature request) is NO way to design a
: language (or, as it happens, any other large software system:-).

And that is not a valid argument against any particular proposed
feature.

Tom Payne

t...@cs.ucr.edu

unread,
Sep 12, 2001, 7:26:01 AM9/12/01
to
Marcin 'Qrczak' Kowalczyk <qrc...@knm.org.pl> wrote:
: Tue, 11 Sep 2001 12:26:04 +0000 (UTC), t...@cs.ucr.edu <t...@cs.ucr.edu> pisze:

:> WORKAROUND_7
:> > eval( c and "<expression a>" or "<expression b>" )
:> I don't like this hack either, but under interpretative
:> execution it's probably more efficient than creating
:> one-member lists (see WORKAROUND_3).

: I don't believe.

You're right; it's way slower. (For reasons that now make no sense to
me, I had hoped that eval cached its translated code.)

Tom Payne

t...@cs.ucr.edu

unread,
Sep 12, 2001, 7:34:54 AM9/12/01
to
Terry Reedy <tjr...@home.com> wrote:

: <t...@cs.ucr.edu> wrote in message news:9nkvss$cmq$1...@glue.ucr.edu...

I agree that "most" real examples fall into this category, but we
still need a general selection operator for the rest.

Also, using the short-circuited evaluation of logical operators for
selection is something of a hack. Sure it's an idiom that people
can get used to, but I would prefer code to say what it means more
directly.

Tom Payne

Alex Martelli

unread,
Sep 12, 2001, 7:56:09 AM9/12/01
to
<t...@cs.ucr.edu> wrote in message news:9nnf0d$5qf$2...@glue.ucr.edu...
...

> : Exactly, except it's not a non-sequitur. "Just satisfying people"
> : (by meeting every popular feature request) is NO way to design a
> : language (or, as it happens, any other large software system:-).
>
> And that is not a valid argument against any particular proposed
> feature.

Sure! But the mistake in the PEP is putting forward the "what's
wrong with just satisfying people" rhetorical question as an
argument FOR a proposed feature. It's a grossly invalid argument
and IMHO it should be either removed from the PEP, or clearly
marked as such -- invalid as an argument.

The need to keep the language small and simple is an argument
against _every_ feature (new and old: I just love it when
Python is able to shed old features that don't fully pull
their weight, although that's always harder to do than "not
adding new ones", because of backwards compatibility issues).

Any proposed feature must provide advantages large enough to
overcome this indispensable barrier to entry. I think the
proposed conditional operator would be just about at the
threshold (I wouldn't particularly care either way if it
got in or stayed out) EXCEPT for the risk that it may in
fact encourage people to write more lambda's rather than
named local functions, which I see as a substantial minus.


Alex

Alex Martelli

unread,
Sep 12, 2001, 9:29:23 AM9/12/01
to
"Gareth McCaughan" <Gareth.M...@pobox.com> wrote in message
news:slrn9pt5k6.18fr....@g.local...

It ain't *CLEAN*, but then the whole caboodle is hardly
spotless anyway. But *easy*, it IS:

class Quadrivial:
def __init__(self):
import sys
caller = sys._getframe(1)
self.ll = caller.f_locals
self.gg = caller.f_globals
def __getitem__(self, key):
return eval(key, self.gg, self.ll)

a=23
b=42
def f():
b=97
c=74
print ">> %(b+100)s %(a*10)s %(c+1000)s"%Quadrivial()

f()

will print

>> 197 230 1074

just as expected/desired.


On whether the Python language should be changed to
*encourage* the use of such techniques, respondant
says no further. (but, it IS fun:-).


Alex

Marcin 'Qrczak' Kowalczyk

unread,
Sep 12, 2001, 10:16:50 AM9/12/01
to
Wed, 12 Sep 2001 13:56:09 +0200, Alex Martelli <al...@aleax.it> pisze:

> I think the proposed conditional operator would be just about at
> the threshold (I wouldn't particularly care either way if it got in
> or stayed out) EXCEPT for the risk that it may in fact encourage
> people to write more lambda's rather than named local functions,
> which I see as a substantial minus.

If we prefer list comprehensions to for loops with appends,
in this case it encourages in the right direction.

Joshua Marshall

unread,
Sep 12, 2001, 10:43:15 AM9/12/01
to
t...@cs.ucr.edu wrote:
> Bernhard Herzog <b...@intevation.de> wrote:
> [...]
> : Another way that come to mind:

> : <expr> if <cond> else <expr>

One thing I don't like about this suggestion is that <cond> is
evaluated before the first <expr> is [potentially] evaluated, even
though <expr> syntactically precedes <cond>.

Alex Martelli

unread,
Sep 12, 2001, 11:09:26 AM9/12/01
to
"Marcin 'Qrczak' Kowalczyk" <qrc...@knm.org.pl> wrote in message
news:slrn9purii...@qrnik.zagroda...

> Wed, 12 Sep 2001 13:56:09 +0200, Alex Martelli <al...@aleax.it> pisze:
>
> > I think the proposed conditional operator would be just about at
> > the threshold (I wouldn't particularly care either way if it got in
> > or stayed out) EXCEPT for the risk that it may in fact encourage
> > people to write more lambda's rather than named local functions,
> > which I see as a substantial minus.
>
> If we prefer list comprehensions to for loops with appends,
> in this case it encourages in the right direction.

Good point! Yes, a conditional operator might be of some
help in writing a list comprehension in certain cases. I
can't think, offhand, of a real-life example where I felt
that need, but theoretical examples are easy to construct.


Alex

Rainer Deyke

unread,
Sep 12, 2001, 1:03:17 PM9/12/01
to
"Joshua Marshall" <jmar...@mathworks.com> wrote in message
news:9nnsa3$bjl$1...@news.mathworks.com...

There is a precedent though.

[<expr> for i in [0] if <cond>]

Strangely enough, list comprehensions without 'for' are forbidden. If they
weren't, you write a conditional expression like this:

([<expr> if <cond>] + [<else-expr> if not <cond>])[0]

This is very ugly (and evalutes <cond> twice). If the '<expr> if <cond>
else <expr>' form was accepted, it would be syntactically consistent with
for-less list comprehensions:

[<expr> if <cond>] # for-less list comprehension
[<expr> if <cond> else <expr>] # list literal

However, it would not fit well with list comprehensions that have a 'for':

[<expr> if <cond> for i in range(5)] # Syntax error
[<expr> for i in range(5) if <cond> else <expr>] # Syntax error
# and ambiguous intent

Conclusion: any conditional expression syntax that uses the 'if' keyword is
likely to be confusing if used in a list comprehension. Maybe this
confusion could be avoided by carefully updating the list comprehension
syntax.


--
Rainer Deyke (ro...@rainerdeyke.com)
Shareware computer games - http://rainerdeyke.com
"In ihren Reihen zu stehen heisst unter Feinden zu kaempfen" - Abigor


Terry Reedy

unread,
Sep 12, 2001, 1:09:45 PM9/12/01
to

<t...@cs.ucr.edu> wrote in message news:9nnh8u$5qf$4...@glue.ucr.edu...

> Terry Reedy <tjr...@home.com> wrote:
>
> : <t...@cs.ucr.edu> wrote in message
news:9nkvss$cmq$1...@glue.ucr.edu...
> :> : WORKAROUND_2: (this SOMETIMES works)
> :> : > x = c and a or b
>
> :> The problem of determining whether or not a given expression ever
> :> evaluates to false is equivalent to determining whether a given
> : Turing
> :> machine halts, i.e., the general case is not algorithmically
> : solvable.
>
> : True, but so what? Most real examples seem to involve constants
that
> : are triviallly either true or false or simple expressions that are
> : trivial to decide in context.
>
> I agree that "most" real examples fall into this category, but we
> still need a general selection operator for the rest.

For which there *is* the sequence[0] hack, which I readily admit is
very much of a hack.

> Also, using the short-circuited evaluation of logical operators for
> selection is something of a hack. Sure it's an idiom that people
can get used to,

Let me admit it here. I *like* the and/or hack/idiom because I
thought of it all by myself when I had occasion to need the equivalent
of C's :/; (which I also used freely).

> but I would prefer code to say what it means more directly.

I would not mind a direct conditional expression being added. I do
mind any pretense that there is no alternative. Since I like the form
of C's conditional, most of the alternatives proposed strike me as
hackier and less gracious than and/or. If it does not conflict with
the existing grammar, I would go for

<condition> if <expression a> else <expression>

as being a Pythonic translation of ? : constructions since I read ? as
'if' and : as 'else'.

Terry J. Reedy


Terry Reedy

unread,
Sep 12, 2001, 1:12:06 PM9/12/01
to

"Joshua Marshall" <jmar...@mathworks.com> wrote in message
news:9nnsa3$bjl$1...@news.mathworks.com...

I agree that the above is backwards.
<cond> if <expr> else <expr>
would remove that objection and make the syntax parallel to
<cond> ? <expr> : <expr>

Terry J. Reedy


Bernhard Herzog

unread,
Sep 12, 2001, 1:22:50 PM9/12/01
to
"Terry Reedy" <tjr...@home.com> writes:

> "Joshua Marshall" <jmar...@mathworks.com> wrote in message
> news:9nnsa3$bjl$1...@news.mathworks.com...
> > t...@cs.ucr.edu wrote:
> > > Bernhard Herzog <b...@intevation.de> wrote:
> > > [...]
> > > : Another way that come to mind:
> >
> > > : <expr> if <cond> else <expr>
> >
> > One thing I don't like about this suggestion is that <cond> is
> > evaluated before the first <expr> is [potentially] evaluated, even
> > though <expr> syntactically precedes <cond>.

I must admit that I don't like it myself for exactly this reason. This
construct is non unusual in natural language, though (at least in
English and German) which is probably the reason why perl has something
like it.

> I agree that the above is backwards.
> <cond> if <expr> else <expr>
> would remove that objection and make the syntax parallel to
> <cond> ? <expr> : <expr>

To me it that's twice backwards but unfortunately in this case that
doesn't make it forwards :-)

Bernhard

--
Intevation GmbH http://intevation.de/
Sketch http://sketch.sourceforge.net/
MapIt! http://mapit.de/

Jeremy Cromwell

unread,
Sep 12, 2001, 5:36:01 PM9/12/01
to pytho...@python.org, mch...@destiny.com
[excellent proto-PEP snipped]

I wonder if I could suggest other specifications.

SPEC_6: Use condition as index of tuple.
The currently legal syntax "x =
(false_val(),true_val())[cond]" would be used, but now
short-circuit.

PRO - [pythonic] [no new keyword] [no new use of
'if']
CON - [changes current functionality]

The 'marker' for causing this to short-circuit is the
indexing of an anonymous, created on-the-fly tuple.
This syntax would even allow "x = (choice_0(),
choice_1(), choice_2(), choice_3())[choice()]"

SPEC_7: Use condition as index "of" tuple.
The syntax "x = cond of (false_val(),true_val())"
would be used.

PRO - [semi-pythonic] [no new use of 'if']
CON - [new keyword]

This syntax would even allow "x = choice() of
(choice_0(), choice_1(), choice_2(), choice_3())"

<END OF SPECS>

While I am personally comfortable with the C syntax
(Sample: a = b ? c : d), I definitely agree that it is
not pythonic. All of the other original SPECs are
"if" based, and to my mind the "if" is strongly
associated with doing DIFFERENT THINGS, while what we
want is different values (see ARG_24).

Note: The only reason I didn't put [hard to read] in
the CON section of SPEC_6 is that it's legal python
syntax.

__________________________________________________
Do You Yahoo!?
Get email alerts & NEW webcam video instant messaging with Yahoo! Messenger
http://im.yahoo.com

Gareth McCaughan

unread,
Sep 12, 2001, 6:42:48 PM9/12/01
to
Alex Martelli wrote:

> Sure! But the mistake in the PEP is putting forward the "what's
> wrong with just satisfying people" rhetorical question as an
> argument FOR a proposed feature. It's a grossly invalid argument
> and IMHO it should be either removed from the PEP, or clearly
> marked as such -- invalid as an argument.

It's not an invalid argument, just a weak one. All else
being equal, the fact that even one user wants a feature
is an argument in its favour. If it's true that many
users want conditional expressions, then that's an
argument for providing them. It's not close to being a
conclusive argument, of course.

> The need to keep the language small and simple is an argument
> against _every_ feature (new and old: I just love it when
> Python is able to shed old features that don't fully pull
> their weight, although that's always harder to do than "not
> adding new ones", because of backwards compatibility issues).

Right. And *that* should probably be in the PEP as an
argument against. Much better than taking out the "lots
of people want it" argument, provided it's true that
lots of people do want it.

Greg Ewing

unread,
Sep 12, 2001, 8:47:53 PM9/12/01
to
Bernhard Herzog <b...@intevation.de> wrote:

> <expr> if <cond> else <expr>

I find myself liking this. To me,

x = a if something else b

reads much more smoothly than

x = if something then a else b

Rainer Deyke wrote:
>
> However, it would not fit well with list comprehensions that have a 'for':
>
> [<expr> if <cond> for i in range(5)] # Syntax error
> [<expr> for i in range(5) if <cond> else <expr>] # Syntax error
> # and ambiguous intent

This can be remedied: give the conditional expression
a precedence lower than any existing operator (which I
think is a good idea anyway), and exclude this level of
precedence from the iterated-over expression of a for loop.


"Terry Reedy" <tjr...@home.com>:

> I agree that the above is backwards.
> <cond> if <expr> else <expr>

No! That sounds way too much like Forth!

--
Greg Ewing, Computer Science Dept, University of Canterbury,
Christchurch, New Zealand
To get my email address, please visit my web page:
http://www.cosc.canterbury.ac.nz/~greg

Terry Reedy

unread,
Sep 12, 2001, 10:02:22 PM9/12/01
to

"Greg Ewing" <gr...@cosc.canterbury.ac.nz> wrote in message
news:3BA00239...@cosc.canterbury.ac.nz...

> "Terry Reedy" <tjr...@home.com>:
>
> > I agree that the above is backwards.
> > <cond> if <expr> else <expr>
>
> No! That sounds way too much like Forth!

It is exactly like C, whose ? : equivalent is the impetus for the
proposed change.
Of course, if you don't like the form of C's conditional expressions,
you won't like its translation into Python.

Terry J. Reedy

Paul Rubin

unread,
Sep 12, 2001, 10:20:16 PM9/12/01
to
"Terry Reedy" <tjr...@home.com> writes:
> > > I agree that the above is backwards.
> > > <cond> if <expr> else <expr>
> >
> > No! That sounds way too much like Forth!
>
> It is exactly like C, whose ? : equivalent is the impetus for the
> proposed change.
> Of course, if you don't like the form of C's conditional expressions,
> you won't like its translation into Python.

How about switching the condition and first expression?

abs = x if x>=0 else -x # find absolute value

I think that's closer to the Python syntax for list comprehensions.

Rainer Deyke

unread,
Sep 13, 2001, 1:31:44 AM9/13/01
to
"Greg Ewing" <gr...@cosc.canterbury.ac.nz> wrote in message
news:3BA00239...@cosc.canterbury.ac.nz...
> Bernhard Herzog <b...@intevation.de> wrote:
>
> > <expr> if <cond> else <expr>
>
> I find myself liking this. To me,
>
> x = a if something else b
>
> reads much more smoothly than
>
> x = if something then a else b
>
> Rainer Deyke wrote:
> >
> > However, it would not fit well with list comprehensions that have a
'for':
> >
> > [<expr> if <cond> for i in range(5)] # Syntax error
> > [<expr> for i in range(5) if <cond> else <expr>] # Syntax error
> > # and ambiguous intent
>
> This can be remedied: give the conditional expression
> a precedence lower than any existing operator (which I
> think is a good idea anyway), and exclude this level of
> precedence from the iterated-over expression of a for loop.

I was actually considering the following interpretations:

[(<expr> if <cond> else <expr>) for i in range(5)]
[(<expr> for i in range(5)) if <cond> else <expr>]

It seems you were thinking of one that never even occurred to me:

[<expr> for i in (range(5) if <cond> else <expr>)]

Rainer Deyke

unread,
Sep 13, 2001, 1:31:45 AM9/13/01
to
"Terry Reedy" <tjr...@home.com> wrote in message
news:OsUn7.4220$5A3.1...@news1.rdc2.pa.home.com...

C's syntax doesn't overload an already existing keyword, and is therefore
arguably clearer. None of the proposed keyword-overloading syntaxes mesh
well with list comprehensions.

t...@cs.ucr.edu

unread,
Sep 13, 2001, 1:50:50 AM9/13/01
to
Rainer Deyke <ro...@rainerdeyke.com> wrote:
: "Terry Reedy" <tjr...@home.com> wrote in message

: news:OsUn7.4220$5A3.1...@news1.rdc2.pa.home.com...
:>
:> "Greg Ewing" <gr...@cosc.canterbury.ac.nz> wrote in message
:> news:3BA00239...@cosc.canterbury.ac.nz...
:> > "Terry Reedy" <tjr...@home.com>:
:> >
:> > > I agree that the above is backwards.
:> > > <cond> if <expr> else <expr>
:> >
:> > No! That sounds way too much like Forth!
:>
:> It is exactly like C, whose ? : equivalent is the impetus for the
:> proposed change.
:> Of course, if you don't like the form of C's conditional expressions,
:> you won't like its translation into Python.

: C's syntax doesn't overload an already existing keyword, and is therefore
: arguably clearer. None of the proposed keyword-overloading syntaxes mesh
: well with list comprehensions.

C syntax does overload the already heavily used colon. Perhaps it
would be better to use semicolon instead of colon.

Tom Payne

Erik Max Francis

unread,
Sep 13, 2001, 1:53:54 AM9/13/01
to
t...@cs.ucr.edu wrote:

> C syntax does overload the already heavily used colon.

The colon isn't used all that much in C. It's used in labels and
switch...case statements, the conditional operator, and bitfields.

> Perhaps it
> would be better to use semicolon instead of colon.

The colon is too overloaded in C, but the semicolon isn't? At least one
semicolon appears in every C statement.

--
Erik Max Francis / m...@alcyone.com / http://www.alcyone.com/max/
__ San Jose, CA, US / 37 20 N 121 53 W / ICQ16063900 / &tSftDotIotE
/ \ There are countless planets, like many island Earths ...
\__/ Konstantin Tsiolkovsky
REALpolitik / http://www.realpolitik.com/
Get your own customized newsfeed online in realtime ... for free!

Ken Seehof

unread,
Sep 13, 2001, 2:16:31 AM9/13/01
to python-list, Rainer Deyke
> "Terry Reedy" <tjr...@home.com> wrote in message
> news:OsUn7.4220$5A3.1...@news1.rdc2.pa.home.com...
> >
> > "Greg Ewing" <gr...@cosc.canterbury.ac.nz> wrote in message
> > news:3BA00239...@cosc.canterbury.ac.nz...
> > > "Terry Reedy" <tjr...@home.com>:
> > >
> > > > I agree that the above is backwards.
> > > > <cond> if <expr> else <expr>
> > >
> > > No! That sounds way too much like Forth!
> >
> > It is exactly like C, whose ? : equivalent is the impetus for the
> > proposed change.
> > Of course, if you don't like the form of C's conditional expressions,
> > you won't like its translation into Python.
>
> C's syntax doesn't overload an already existing keyword, and is therefore
> arguably clearer. None of the proposed keyword-overloading syntaxes mesh
> well with list comprehensions.

Seems like


<expr> if <cond> else <expr>

is analogous to
'[' <expr> for <var> in <sequence> ']'

Of course, in the former case, the [] is missing because the resulting
expression
is not a list.

Since this is python, :"<expr> if <cond> else <expr>" is the most
appropriate
order, since it unambiguously yields expected results consistent with
English.

If we use the other order, with the right keyword it would be:
<cond> then <expr> else <expr>
but that smells bad somehow, and it introduces a new keyword. :-(

Also, I would propose that ... else None should be implicit.
>>> print 'eeek' if pi == 3
None

But this example is giving me second thoughts about the whole idea.
People could easily be confused and misinterpret the syntax as:
<statement> if <cond> [ else <statement> ]

- Ken

pi...@cs.uu.nl

unread,
Sep 13, 2001, 4:17:50 AM9/13/01
to
>>>>> Erik Max Francis <m...@alcyone.com> (EMF) writes:

EMF> t...@cs.ucr.edu wrote:
>> C syntax does overload the already heavily used colon.

EMF> The colon isn't used all that much in C. It's used in labels and
EMF> switch...case statements, the conditional operator, and bitfields.

>> Perhaps it
>> would be better to use semicolon instead of colon.

EMF> The colon is too overloaded in C, but the semicolon isn't? At least one
EMF> semicolon appears in every C statement.

False! The semicolon is used to make a statement out of an expression.

--
Piet van Oostrum <pi...@cs.uu.nl>
URL: http://www.cs.uu.nl/~piet [PGP]
Private email: P.van....@hccnet.nl

Paul Boddie

unread,
Sep 13, 2001, 5:46:56 AM9/13/01
to
"Alex Martelli" <al...@aleax.it> wrote in message news:<9nidr...@enews1.newsguy.com>...

>
> Seconded on both scores. Specifically, adding to Python all the
> features that "lots of people" ask for would ensure Python's
> transformation into a huge, bloated language. *THIS* is "what's

> wrong with just satisfying people", as here rhetorically asked:
> trying to make everybody happy will ensure nobody's happy:-).

Interestingly, whilst I have made use of the ... ? ... : ... construct
in the C family of languages and Java, I rarely want to use it (and
thus rarely miss it) in Python. Most frequently, when I do use it in
the former languages, it is to deal with situations like this:

String outputString = (otherString == null) ? "" : otherString;

In Python, one can use the following instead in this case:

outputString = otherString or ""

Personally, I find complicated uses of ?: difficult to scan and
understand rapidly, contrary to spurious arguments about its supposed
similarity to English language constructs.

Paul

Erik Max Francis

unread,
Sep 13, 2001, 11:18:29 AM9/13/01
to
pi...@cs.uu.nl wrote:

> > The colon is too overloaded in C, but the semicolon isn't? At least
> > one

> > semicolon appears in every C statement.
>
> False! The semicolon is used to make a statement out of an expression.

How does that contradict what I said? What I said was completely
accurate. Each statement contains at least one semicolon.

--
Erik Max Francis / m...@alcyone.com / http://www.alcyone.com/max/
__ San Jose, CA, US / 37 20 N 121 53 W / ICQ16063900 / &tSftDotIotE

/ \ I never think of the future. It comes soon enough.
\__/ Albert Einstein
Alcyone Systems' CatCam / http://www.catcam.com/
What do your pets do all day while you're at work? Find out.

Michael Abbott

unread,
Sep 13, 2001, 12:12:04 PM9/13/01
to
Erik Max Francis <m...@alcyone.com> wrote in
news:3BA0CE45...@alcyone.com:

> pi...@cs.uu.nl wrote:
>
>> > The colon is too overloaded in C, but the semicolon isn't? At least
>> > one semicolon appears in every C statement.
>>
>> False! The semicolon is used to make a statement out of an expression.
>
> How does that contradict what I said? What I said was completely
> accurate. Each statement contains at least one semicolon.

Not quite (though the observation that semicolons convert statements to
expressions isn't quite complete, either). Consider:

if(expression) {}

However, I have to admit I can't think of a *useful* statement which
doesn't contain any semicolons, and the only omission from the statement
above is that the semicolon is also required to complete variable and
struct/class declarations.

Alex Martelli

unread,
Sep 13, 2001, 12:23:34 PM9/13/01
to
"Erik Max Francis" <m...@alcyone.com> wrote in message
news:3BA0CE45...@alcyone.com...
...

> How does that contradict what I said? What I said was completely
> accurate. Each statement contains at least one semicolon.

Does it? What about, e.g:

void loopalot(foobar) {
while(foobar()) {}
}

Isn't this function's body a valid ISO C statement, and where
is the "at least one" semicolon it contains?


Alex

Michael Chermside

unread,
Sep 13, 2001, 5:29:38 PM9/13/01
to pytho...@python.org
> SPEC_6: Use condition as index of tuple.
> The currently legal syntax "x =
> (false_val(),true_val())[cond]" would be used, but now
> short-circuit.

This would seem to me to be a complete non-starter, since it changes the
behavior of tuples into some wierd version of a lazy list. It would
completely and fundamentally change things deep in the heart of Python,
and probably NOT necessarily in a positive way.

> SPEC_7: Use condition as index "of" tuple.
> The syntax "x = cond of (false_val(),true_val())"
> would be used.

It sounds like what you're trying to invent here is a short-circuiting
CASE expression, not a conditional expression. That seems out of scope,
and so I'm inclined to ommit this one. Please, though, let me know if
I'm misunderstanding you.

-- Michael Chermside

Michael Chermside

unread,
Sep 13, 2001, 5:22:34 PM9/13/01
to pytho...@python.org
> If it does not conflict with
> the existing grammar, I would go for
>
> <condition> if <expression a> else <expression>
>
> as being a Pythonic translation of ? : constructions since I read ? as
> 'if' and : as 'else'.
>
> Terry J. Reedy

But that appears to NOT scan like English.

x = finished() if 'Done' else nextValue()

It seems to me that the word "if", in English, can be used in may
flexible ways:

"one if by land two if by sea"

"if you're ready then we'll go, otherwise we'll stay here"

But I can't think of a use in which "if" isn't immediately followed by
the condition.

-- Michael Chermside

Gareth McCaughan

unread,
Sep 13, 2001, 5:25:14 PM9/13/01
to
Terry Reedy wrote:

> > > I agree that the above is backwards.
> > > <cond> if <expr> else <expr>
> >
> > No! That sounds way too much like Forth!
>
> It is exactly like C, whose ? : equivalent is the impetus for the
> proposed change.
> Of course, if you don't like the form of C's conditional expressions,
> you won't like its translation into Python.

It isn't exactly like C, because the C syntax doesn't
abuse the word "if". If you use words from a natural
language, it is best to use them in a way reasonably
compatible with that language. "<condition> if <expression> ..."
completely fails this test, and I too think it could only
appeal to someone who'd got used to it by programming in
Forth.

I don't read "cond ? a : b" in C as "cond if a else b".
Actually, I read it as "cond query a colon b", but that
just indicates that I have C's operators well internalized.
I suggest "cond chooses a or b", though that might be
misleading since "or" has other meanings. "Selects" might
be better than "chooses". Or, as I say, there's "query"
and "colon". :-)

Greg Ewing

unread,
Sep 13, 2001, 6:56:09 PM9/13/01
to
Terry Reedy wrote:
>
> <cond> if <expr> else <expr>
>
> ... is exactly like C, whose ? : equivalent is the impetus for the
> proposed change.

No, it's not, because the C syntax doesn't use
English words in a misleading way. That's what
I was objecting to, not the order of the
operands.

Greg Ewing

unread,
Sep 13, 2001, 6:59:57 PM9/13/01
to
Ken Seehof wrote:
>
> Also, I would propose that ... else None should be implicit.
> >>> print 'eeek' if pi == 3
> None
>
> But ... people could easily be confused and misinterpret the syntax as:

> <statement> if <cond> [ else <statement> ]

That's a good argument for making the else mandatory.
It's less easy to misinterpret

print 'eeek' if pi == 3 else None

It would be even clearer if parentheses were required:

print ('eeek' if pi == 3 else None)

So I suggest that parentheses always be required around
if..else expressions. That would clear up any potential
confusion in list comprehensions, and anywhere else that
it might occur.

Greg Ewing

unread,
Sep 13, 2001, 7:03:17 PM9/13/01
to
Rainer Deyke wrote:
>
> I was actually considering the following interpretations:
>
> [(<expr> for i in range(5)) if <cond> else <expr>]

That one isn't even an interpretation, it's nonsense.
Unless you mean it to mean

[<expr> for i in range(5)] if <cond> else [<expr>]

and I wouldn't mind in the least being required to
write it like that if that's what I wanted.

Greg Weeks

unread,
Sep 13, 2001, 10:20:57 PM9/13/01
to
Michael Chermside (mch...@destiny.com) wrote:
: ARG_23: Lots of people ask for it.
: Lots of people ask for a conditional expression. Even if the
: other pro arguments don't convince you, what harm is there in
: settling this one? For a LONG time, we used to hear
: complaints about how Python lacked "+=", "*=" and such; now
: that it has them, the complaints have died to a trickle.
: What's wrong with just satisfying people?

*Which* people? People who want additions post all the time. People who
don't want additions do not post all the time. We just go about our
business, and the next thing we know a half-baked nested scopes proposal
has been implemented.

Okay, that was bitter. I apologize to those who are fond or proud of
nested scopes. But I consider it one of a handful of minor blemishes on my
favorite language. Still, I should focus on the word "minor". Python is
not going to hell in a handbasket. I am, though, concerned that it is
getting slightly worse instead of slightly better.

Anyway, if you satisfy all the people who want additions you'll end up with
Perl and TIMTOWTDI. Besides, if you really want to satisfy the majority of
people, just give them Perl. For some reason, your average hardware
engineer just loves Perl and hasn't the slightest interest in Python.

I admit that these are just my impressions. I don't have the time (or the
experience) to have a firm opinion. But my impression is that we're
messing with a language that is better off left alone. We should be
working on spreading the word and implementing new modules, not on
administering what may turn out to be the death of a thousand cuts.

Regards,
Greg

Rainer Deyke

unread,
Sep 13, 2001, 10:45:26 PM9/13/01
to
"Greg Ewing" <gr...@cosc.canterbury.ac.nz> wrote in message
news:3BA13B35...@cosc.canterbury.ac.nz...

> Rainer Deyke wrote:
> >
> > I was actually considering the following interpretations:
> >
> > [(<expr> for i in range(5)) if <cond> else <expr>]
>
> That one isn't even an interpretation, it's nonsense.

Just because it isn't legal Python (now or with conditional statements)
doesn't mean it's nonsense.

> Unless you mean it to mean
>
> [<expr> for i in range(5)] if <cond> else [<expr>]

Yes, that is what I mean.

> and I wouldn't mind in the least being required to
> write it like that if that's what I wanted.

You're not addressing the real point. With the '<expr> if <cond> else
<expr>' syntax, an 'if' enclosed in brackets has two very different meanings
depending on whether or not there is an else. This makes Python harder to
read, write, and grok - *unless* the new syntax is somehow conceptually
unified with the list comprehension syntax.


One problem is that list comprehension syntax is already confusing:

[i for i in range(5)]

It's easy to think of 'i for i in range(5)' as an expression that yields
multiple values and can therefore only exist in the special context of a
list literal. This view is unfortunately incorrect:

[(x, y) for x in range(5) for y in range(5)]

My instincts tell me that '(x, y) for x in range(5)' is evaluated for each
'y' in 'range(5)', but in fact it's the other way around: 'for x in
range(5)' is the outer loop and 'for y in range(5)' is the inner. The 'for'
and 'if' clauses in a list comprehension do not act like expressions.
Imagine then the confusion if the '<expr> if <cond> else <expr>', which
*does* act like an expression, was added to the language.

Peter Mayne

unread,
Sep 12, 2001, 5:10:33 AM9/12/01
to
An idea borrowed from BLISS...

In BLISS, all statements are expressions, to the point that BEGIN and END
are interchangeable with ( and ).

The assignment statement
x = 1
has the value 1, as does the expression statement
1

Simple statements such as "print" return None.

Compound statements have the obvious value:

value =
if x>3:
4
else:
5

This if statement has the value 4 or 5, depending on the value of x.

Now we get complicated.

sum = 0
i = 0
total =
while 1:
if i==10:
break sum
sum += i
i += 1

The while statement has the value of the last statement executed, which in
this case is "break sum". Consequently, "total" has the value of the while
statement.

An equivalent to the above is

total =
sum = 0
for i in range(10):
sum += i

Since "sum += i" is the last statement executed, total has the final value
of sum.

If statements and expressions are the same thing, then there's no need to
worry about special syntax for conditional expressions, because the language
can already handle such things by definition.

PJDM
--
Peter Mayne
IBM GSA (but the opinions are mine)
Canberra, ACT, Australia
This post is covered by Sturgeon's Law.


Markus Schaber

unread,
Sep 14, 2001, 5:34:53 AM9/14/01
to
Hi,

Gareth McCaughan <Gareth.M...@pobox.com> schrub:

> It isn't exactly like C, because the C syntax doesn't
> abuse the word "if". If you use words from a natural
> language, it is best to use them in a way reasonably
> compatible with that language. "<condition> if <expression> ..."
> completely fails this test, and I too think it could only
> appeal to someone who'd got used to it by programming in
> Forth.

What about "(<cond>: return <expr> [else return <expr])" - yes, I want
to make the else optional (returning None otherwise). But the () around
it have to be there.

May be even "(<cond>: <expr> [else <expr>])" would be usable.

In my thinking of natural and mathematical language, the : is a way of
indicating that the condition proposes the expression.

markus
--
"The strength of the Constitution lies entirely in the determination of
each citizen to defend it. Only if every single citizen feels duty
bound to do his share in this defense are the constitutional rights
secure." -- Albert Einstein

Skip Montanaro

unread,
Sep 14, 2001, 8:37:46 AM9/14/01
to Markus Schaber, pytho...@python.org

Markus> What about "(<cond>: return <expr> [else return <expr])"

All you're saving is a single word and a colon:

if <cond>: return <expr>
else: return <expr>

--
Skip Montanaro (sk...@pobox.com)
http://www.mojam.com/
http://www.musi-cal.com/

Alex Martelli

unread,
Sep 14, 2001, 9:51:36 AM9/14/01
to
"Michael Abbott" <mic...@rcp.co.uk> wrote in message
news:Xns911BAEFC8E6D...@194.238.50.13...
...

> However, I have to admit I can't think of a *useful* statement which
> doesn't contain any semicolons, and the only omission from the statement

I keep proposing my loopalot "metafunction" as having a quite possibly
useful C statement that doesn't contain any semicolons (I posted before
I saw this answer, and it wasn't compliant ISO C in my first post,
as the argument type was missing - I've been Pythoning too much!-):

void loopalot(int (*somefunc)(void)) {
while(somefunc()) {}
}

Function loopalot calls its function-pointer argument somefunc
one or more times, until the result of one of those calls is 0.
Presumably (*somefunc)() has some side effect as well as
returning 0 (stop looping) or non-0 (keep looping), of course,
but that's up to the caller.


Alex

maxm

unread,
Sep 14, 2001, 10:29:38 AM9/14/01
to
> In Python, one can use the following instead in this case:
>
> outputString = otherString or ""
>
> Personally, I find complicated uses of ?: difficult to scan and
> understand rapidly, contrary to spurious arguments about its supposed
> similarity to English language constructs.

Besides ... what could be simpler than using the fact that booleans in
Python is either 1 or 0:

#################################
>>> a=3
>>> b=4
>>> print ('number two', 'number one')[a < b]
>>> number one

or if you want to get the result of a functionwith only the choosen function
evaluated:

#################################
>>> def n1():
>>> return 'Number one'
>>> def n2():
>>> return 'Number two'
>>> print (n2, n1)[a < b]()
>>> Number one

Any sane Python programmer will grasp those IMMEDIATELY!

;-)

Regards Max M


Ralph Corderoy

unread,
Sep 14, 2001, 11:18:20 AM9/14/01
to
Hi,

> > The colon is too overloaded in C, but the semicolon isn't? At

> > least one semicolon appears in every C statement.


>
> False! The semicolon is used to make a statement out of an
> expression.

Not always.

do {
foo();
} while (x);

The last semi-colon isn't making a statement from an expression. it's
merely helping with error recovery in the parser.


Ralph.

Pete Shinners

unread,
Sep 13, 2001, 6:58:24 PM9/13/01
to
>> <condition> if <expression a> else <expression>
>
> But that appears to NOT scan like English.
> "one if by land two if by sea"

num_rings = 1 if enemy.onland() else 2

not the most graceful english, heh. and i suppose
it works if they are nested..

num_rings = 1 if onland() else 2 if onsea() else 3

t...@cs.ucr.edu

unread,
Sep 14, 2001, 1:39:14 PM9/14/01
to
Pete Shinners <pe...@visionart.com> wrote:
:>> <condition> if <expression a> else <expression>

To fully reflect the "one if by land, two if by sea" construct of
English, we need to adopt the implicit "else None" idea. Then

1 if by_land() else 2 if by_sea()

means

1 if by_land() else 2 if by_sea() else None

which is what the corresponding english means.

Tom Payne

James_...@i2.com

unread,
Sep 14, 2001, 2:21:31 PM9/14/01
to pytho...@python.org

With apologies for possibly having missed some parts of this thread . . .

Given:
1) nested scopes, and
2) recent proposals becoming more and more complicated and convoluted --
e.g., embedding "break" and "return" statements inside if:else: expression
syntax, highly overloaded meanings of if:else: ,
inside/outside/upside/downside ordering of if:else: keywords, etc., . . .

Why not just start with something simple like a builtin "cond" function
approximating the following:

Python 2.2a1 (#21, Jul 18 2001, 04:25:46) [MSC 32 bit (Intel)] on win32
Type "copyright", "credits" or "license" for more information.
>>>
>>> from __future__ import nested_scopes
>>>
>>> def cond(expr, iftrue, iffalse=lambda:None):
... if expr: return iftrue()
... return iffalse()
...
>>> x = -2
>>> abs = cond(x>=0, lambda:x, lambda:-x)
>>> abs
2
>>> l = [7,8,9]
>>> firstItem = cond(len(l)>0, lambda:l[0])
>>> firstItem
7
>>> l = []
>>> firstItem = cond(len(l)>0, lambda:l[0])
>>> print firstItem
None
>>>

Seems like this would handle many of the common, simple cases.

Jim

ps. Then attention could be focused on defining a mechanism for
general-purpose, unnamed, "in-place" code blocks. If we had such, we could
then create many convenient idioms using functions and methods -- instead
of constantly wrangling with new syntactic forms and keywords.

Marcin 'Qrczak' Kowalczyk

unread,
Sep 14, 2001, 3:22:47 PM9/14/01
to
Fri, 14 Sep 2001 11:21:31 -0700, James_...@i2.com <James_...@i2.com> pisze:

> Why not just start with something simple like a builtin "cond" function
> approximating the following:

I don't like prepending 'lambda:' to both alternatives.

abs = if x>=0 then x else -x
or
abs = if x>=0: x else: -x
looks more readable than


abs = cond(x>=0, lambda:x, lambda:-x)

for me.

> ps. Then attention could be focused on defining a mechanism for
> general-purpose, unnamed, "in-place" code blocks. If we had such,
> we could then create many convenient idioms using functions and
> methods -- instead of constantly wrangling with new syntactic forms
> and keywords.

Yes, but the syntax of explicitly creating such block would be a bit
annoying if they would have to be created for e.g. loops.

--
__("< Marcin Kowalczyk * qrc...@knm.org.pl http://qrczak.ids.net.pl/
\__/
^^ SYGNATURA ZASTĘPCZA
QRCZAK

Michael Chermside

unread,
Sep 14, 2001, 4:29:59 PM9/14/01
to pytho...@python.org
James_Althoff writes:
> With apologies for possibly having missed some parts of this thread . . .
>
> Given:
> 1) nested scopes, and
> 2) recent proposals becoming more and more complicated and convoluted --
> e.g., embedding "break" and "return" statements inside if:else: expression
> syntax, highly overloaded meanings of if:else: ,
> inside/outside/upside/downside ordering of if:else: keywords, etc., . . .
>
> Why not just start with something simple like a builtin "cond" function
> approximating the following:
>
>

I *think* I can answer your question by quoting from the PEP:

> WORKAROUND_1: (this DOESN'T WORK!)
> > def cond(c, a, b):
> > if c: return a
> > else: return b
> > x = cond(c, a, b)
> This fails, because it does not short-circuit... the
> arguments the the function are always evaluated before
> the function is invoked. Thus, for instance, the
> following would not work properly when a == 0:
> > x = cond( a==0, DEFAULT_VAL, 100/a )

Do you see why the "cond" solution won't do?

-- Michael Chermside


Michael Chermside

unread,
Sep 14, 2001, 4:24:16 PM9/14/01
to pytho...@python.org
Markus> What about "(<cond>: return <expr> [else return <expr])"

Skip> All you're saving is a single word and a colon:
Skip>
Skip> if <cond>: return <expr>
Skip> else: return <expr>
Skip>

No, he's actually proposing a major change to the interpretation of
"return" in Python -- which is why I don't particularly like this syntax
(but perhaps this objection can be patched up!).

For instance, consider the following (written using the and-or trick):

def f(a,b=1):
x = a > 0 and a or b
return x ** 2 - 1

Now, if we tried to re-write this in Markus's syntax, we'd get the
following:

def f(a,b=1):
x = a > 0: return a else return b
return x ** 2 - 1

Apparently Markus's syntax implies that after a colon appearing in a
statement (as opposed to other, normal :'s in Python), the "return"
keyword no longer means to return from a function.

Markus... did I mis-interpret? Do you still think this is a useful syntax?

-- Michael Chermside

James_...@i2.com

unread,
Sep 14, 2001, 4:35:06 PM9/14/01
to pytho...@python.org

Marcin Kowalczyk wrote:
> abs = if x>=0 then x else -x
>or
> abs = if x>=0: x else: -x
>looks more readable than
> abs = cond(x>=0, lambda:x, lambda:-x)
>for me.

That's a fair opinion. But you have to admit that the last one beats the
heck out of the first two in terms of implementation issues.

And is not nearly as humorous as
abs = (x>=0 and [x] or [-x])[0]
as an available workaround. ;-)

Jim


Michael Chermside

unread,
Sep 14, 2001, 4:36:39 PM9/14/01
to pytho...@python.org
James_Althoff writes:
> With apologies for possibly having missed some parts of this thread . . .
>
> Given:
> 1) nested scopes, and
> 2) recent proposals becoming more and more complicated and convoluted --
> e.g., embedding "break" and "return" statements inside if:else: expression
> syntax, highly overloaded meanings of if:else: ,
> inside/outside/upside/downside ordering of if:else: keywords, etc., . . .
>
> Why not just start with something simple like a builtin "cond" function
> approximating the following:
>
>

James:

Now it's ME who's apologizing, for not reading YOUR post well enough.

I somehow overlooked the fact that you are passing FUNCTIONS not VALUES,
through the use of lambda. Others have pointed out that the lambda
functions can't make reference to variables in the current scope, but
since that is FIXED! since the introduction of nested_scope, I'm
disregarding it.

So your solution DOES work. I'll definitely add it to the PEP as another
workaround... awkward, due to the need to type the lambdas, but
certainly usable.

-- Michael Chermside

PS: thanks to EVERYONE who's been writing. I've only been RESPONDING to
a small portion of the postings, but I've been gleaning LOTS of useful
ideas, arguments, and phrasings to use for the PEP.


Terry Reedy

unread,
Sep 14, 2001, 5:21:14 PM9/14/01
to

<James_...@i2.com> wrote in message
news:mailman.100049185...@python.org...

> Why not just start with something simple like a builtin "cond"
function
> approximating the following:
> >>> def cond(expr, iftrue, iffalse=lambda:None):
> ... if expr: return iftrue()
> ... return iffalse()

Because, as explained before, both iftrue and iffalse expressions are
always both evaluated, which defeats one of the purposes of
conditional expressions, which is to not evaluate expressions that
will raise an exception.

Terry J. Reedy

James_...@i2.com

unread,
Sep 14, 2001, 5:52:41 PM9/14/01
to pytho...@python.org

Terry J. Reedy wrote:
><James_...@i2.com> wrote in message

>> Why not just start with something simple like a builtin "cond"
>function
>> approximating the following:
>> >>> def cond(expr, iftrue, iffalse=lambda:None):
>> ... if expr: return iftrue()
>> ... return iffalse()
>
>Because, as explained before, both iftrue and iffalse expressions are
>always both evaluated, which defeats one of the purposes of
>conditional expressions, which is to not evaluate expressions that
>will raise an exception.
>
>Terry J. Reedy

Even though Michael tried to clarify this confusion already, I guess I will
try again since it has come up twice now.

Key Point: the workaround I proposed does *not* have the problem mentioned
above because the "cond" function takes *functions* for arguments.

Observe:

Python 2.2a1 (#21, Jul 18 2001, 04:25:46) [MSC 32 bit (Intel)] on win32
Type "copyright", "credits" or "license" for more information.
>>>
>>> from __future__ import nested_scopes
>>>

>>> def cond(expr, iftrue, iffalse=lambda:None):
... if expr: return iftrue()
... return iffalse()

...
>>> x = 0
>>> xinv = cond(x!=0, lambda:1/x)
>>> print xinv
None
>>>

Notice that lambda:1/x is not a problem. It is not evaluated when x==0.

This "cond" function is using the same idea as the "cond" special form in
Lisp and the ifTrue:ifFalse: method in Smalltalk -- i.e., pass in
unevaluated "result" expressions and only evaluate the appropriate one
according to the controlling "conditional" expression.

Hope this makes it clearer.

Jim


t...@cs.ucr.edu

unread,
Sep 16, 2001, 6:19:49 PM9/16/01
to
James_...@i2.com wrote:

: Marcin Kowalczyk wrote:
:> abs = if x>=0 then x else -x
:>or
:> abs = if x>=0: x else: -x
:>looks more readable than
:> abs = cond(x>=0, lambda:x, lambda:-x)
:>for me.

: That's a fair opinion. But you have to admit that the last one beats the
: heck out of the first two in terms of implementation issues.

As far as I can tell, it doesn't work if x is a local variable. Have
you actually tried it?

: And is not nearly as humorous as


: abs = (x>=0 and [x] or [-x])[0]
: as an available workaround. ;-)

No question.

Tom Payne

Greg Ewing

unread,
Sep 16, 2001, 8:30:45 PM9/16/01
to
Rainer Deyke wrote:
>
> The 'for'
> and 'if' clauses in a list comprehension do not act like expressions.
> Imagine then the confusion if the '<expr> if <cond> else <expr>', which
> *does* act like an expression, was added to the language.

Maybe some other word than 'if' should be used, then, such as

<expr> when <cond> else <expr>

t...@cs.ucr.edu

unread,
Sep 16, 2001, 10:42:38 PM9/16/01
to
t...@cs.ucr.edu wrote:
: James_...@i2.com wrote:

: : Marcin Kowalczyk wrote:
: :> abs = if x>=0 then x else -x
: :>or
: :> abs = if x>=0: x else: -x
: :>looks more readable than
: :> abs = cond(x>=0, lambda:x, lambda:-x)
: :>for me.

: : That's a fair opinion. But you have to admit that the last one beats the
: : heck out of the first two in terms of implementation issues.

: As far as I can tell, it doesn't work if x is a local variable. Have
: you actually tried it?

Oops! I failed to note that you were presuming nested scopes.

Tom Payne


Don O'Donnell

unread,
Sep 17, 2001, 3:58:43 AM9/17/01
to
Michael Chermside wrote:
...
>Abstract
>
> A Frequently Asked Question by Python newbies is "How do I do the
> equivalent of C's ?: syntax?". The answers, while fairly well
> documented, are imperfect or incomplete. Thus many have suggested
> adding some syntax to Python for this purpose. The goal of this
> PEP is to gather all of the commonly proposed options and the
> arguments both pro and con. It will thus serve as a focal point
> for discussion and perhaps even be eventually accepted or
> rejected.
>
...

When I first started programming with Python I was disappointed by the
absence of the C type conditional expression. However, after having
written some tens of thousands of lines of Python code, there were very
few times when I really felt a need for it, being able to use the
workarounds most of the time. So to me, this addition to the language
is not a high priority, and I would rather see scarce developer
resources used in other areas.

But, just in case this PEP is approved, and the conditional expression
makes it's way into the language, I would like to contribute my humble
opinion to the syntax arguments.

I cast my vote for SPEC_1.
...
> SPEC_1: Use the "C syntax".
> The following production would be added to Python syntax:
> expression: expression ? exprression : expression
> Since "?" is not currently used in Python, this would never
> be syntactically ambiguous. Sample: a = b ? c : d
>
> PRO - [familiar to programmers]
> CON - [hard to read] [not pythonic]
...

The arguments against it, [hard to read] and [not pythonic], I believe
are invalid.

<exp1> ? <exp2> : <exp3>

This expresses the meaning clearly and succinctly (which is a very
Pythonic thing to do) and is very easy to read:
1. <exp1> - evaluate it
2. ? - makes it a query, is it true?
3. <exp2> - if true, evaluate it
4. <exp3> - else, evaluate it

I don't believe the use of special symbols ? and : is any less Pythonic
than the use of other symbols to denote operators which are also
borrowed from the C language.

The use of key words 'if', 'then', 'else' rather than symbols (?:) seems
an unnecessary COBOLization of Python, and would not add anything to
it's readability (except perhaps to a non-programmer).

Following this line of reasoning we should write:
>>> a indexed by i = call f using x, y
rather than:
>>> a[i] = f(x,y)

Exactly why are the symbols [] and () considered Pythonic but ? and :
are not?

My other objection to the alternate syntax suggestions in this PEP and
thread, which all advocate using key words "if", "then", "else" in some
combination or order, is that the use of these words makes it look too
much like a statement rather than an expression. Expressions should use
simple operators like + - * / % < > <= >= == etc., not key words. Key
words should signal a statement, like: for, while, print, if, etc.

Use of the if/then/else keyword syntax would lead to the following
anomalies and possible confusion:

Assuming SPEC_2/SPEC_3:
>>> a = 5
>>> if a > 0 then print "a is positive" \ # invalid conditional expr
else print "a is not positive" # continued on second line
SyntaxError: invalid syntax, cond expr can not contain stmt

>>> if a > 0: print "a is positive" # valid if stmt
else: print "a is not positive"
a is positive

Or, even more confusing, assuming SPEC_4:
>>> a = 5
>>> if a > 0: print "a is positive" \ # invalid conditional expr
else: print "a is not positive" # continued on second line
SyntaxError: invalid syntax, cond expr can not contain stmt

>>> if a > 0: print "a is positive" # valid if stmt, looks almost
else: print "a is not positive" # like the invalid cond above
a is positive

I know that the conditional expression will normally appear imbedded in
some statement, not standing alone as above. But just the thought of
writing:
>>> a = if ... else ...
seems weird to me. Anything starting with "if" is a statement to me.
And that's the way it ought to be.

Just my 2 cents, for what it's worth.

Cheers,
Don

sebastien

unread,
Sep 17, 2001, 4:38:47 AM9/17/01
to
What do you think about this idiom?

>>> a=5; b=2
>>> c=5*[2,3][a==b]
>>> c
10
>>> a=2
>>> c=5*[2,3][a==b]
>>> c
15

Of course it doesn't solve the PEP problem's:
>>> def toto(x):
... print "toto"
... return x+1
...
>>> c=5*[toto(2),toto(3)][a==b]
toto
toto

But for const expressions, do you think it's obfucassed Python?

Markus Schaber

unread,
Sep 17, 2001, 8:52:32 AM9/17/01
to
Hi,

maxm <ma...@normik.dk> schrub:

> Besides ... what could be simpler than using the fact that booleans in
> Python is either 1 or 0:
>
> #################################
>>>> a=3
>>>> b=4
>>>> print ('number two', 'number one')[a < b]
>>>> number one

This does not short-cirquit evaluate.

> or if you want to get the result of a functionwith only the choosen
> function evaluated:
>
> #################################
>>>> def n1():
>>>> return 'Number one'
>>>> def n2():
>>>> return 'Number two'
>>>> print (n2, n1)[a < b]()
>>>> Number one
>
> Any sane Python programmer will grasp those IMMEDIATELY!

That does short-cirquit, but has limits on the expressions you can use
as n1 and n2 (may be that gamma and nested scopes help here).

Markus Schaber

unread,
Sep 17, 2001, 9:06:29 AM9/17/01
to
Hi,

Skip Montanaro <sk...@pobox.com> schrub:

>
> Markus> What about "(<cond>: return <expr> [else return <expr])"
>
> All you're saving is a single word and a colon:
>
> if <cond>: return <expr>
> else: return <expr>

But my version doesn't overload the if keyword, the second proposal
doesn't overload the if and return keywords.

And with requiring the brackets, it should be easier for machine and
human parsers to distinguish between the if: else: statements and the
conditional expression.

Markus Schaber

unread,
Sep 17, 2001, 11:01:29 AM9/17/01
to
Hi,

Michael Chermside <mch...@destiny.com> schrub:

> def f(a,b=1):
> x = a > 0: return a else return b
> return x ** 2 - 1
>
> Apparently Markus's syntax implies that after a colon appearing in a
> statement (as opposed to other, normal :'s in Python), the "return"
> keyword no longer means to return from a function.

Yes, but I wanted to always have brackets "()" around it (just as we
have the [] around the list comprehension)

x = (a > 0: return a else return b)

Currently, return and : both can't appear inside of (), and so it
should be clear which return is meant.

> Markus... did I mis-interpret? Do you still think this is a useful
> syntax?

My objection to this would be that it is too much to type, and that's
why I made a second proposal some lines later.

I'm rather shure that it is impossible to invent conditional expressios
without redefining something or inventing new keywoards or symbols.

And in my case I define new meanings for :, else and (in the first
proposal) return in a context where they are illegal now, so it
shouldn't break any existing code.

Markus Schaber

unread,
Sep 17, 2001, 11:21:03 AM9/17/01
to
Hi,

Marcin 'Qrczak' Kowalczyk <qrc...@knm.org.pl> schrub:

>> ps. Then attention could be focused on defining a mechanism for
>> general-purpose, unnamed, "in-place" code blocks. If we had such,
>> we could then create many convenient idioms using functions and
>> methods -- instead of constantly wrangling with new syntactic forms
>> and keywords.
>
> Yes, but the syntax of explicitly creating such block would be a bit
> annoying if they would have to be created for e.g. loops.

I just remembered my steps in TCL. There, even loops are commands which
get some unnamed code blocks as arguments (the condition and the body).

Maybe we could do the same, based on indentation instead of {}s.

But I see some problems in handling the if: else: this way, there the
else: command needs to know the result of the corresponding if:
command.

James_...@i2.com

unread,
Sep 17, 2001, 12:30:11 PM9/17/01
to pytho...@python.org

Tom Payne wrote:
>As far as I can tell, it doesn't work if x is a local variable. Have
>you actually tried it?

Yes. And the following example Python run was included in my original
post:

Python 2.2a1 (#21, Jul 18 2001, 04:25:46) [MSC 32 bit (Intel)] on win32
Type "copyright", "credits" or "license" for more information.
>>>
>>> from __future__ import nested_scopes
>>>
>>> def cond(expr, iftrue, iffalse=lambda:None):
... if expr: return iftrue()
... return iffalse()
...

>>> x = -2


>>> abs = cond(x>=0, lambda:x, lambda:-x)

>>> abs
2
>>> l = [7,8,9]
>>> firstItem = cond(len(l)>0, lambda:l[0])
>>> firstItem
7
>>> l = []
>>> firstItem = cond(len(l)>0, lambda:l[0])
>>> print firstItem
None
>>>

Jim

Michael Chermside

unread,
Sep 18, 2001, 10:53:32 AM9/18/01
to pytho...@python.org, s.k...@laposte.net

Yes, actually, I do. It certainly doesn't "say what it means".

-- Michael Chermside

Michael Chermside

unread,
Sep 18, 2001, 10:50:46 AM9/18/01
to pytho...@python.org, do...@home.com
In <http://mail.python.org/pipermail/python-list/2001-September/064989.html>

Don O'Donnel wrote:
...
> ...to me, this addition to the language is not a high priority, and I


> would rather see scarce developer resources used in other areas.
>
> But, just in case this PEP is approved, and the conditional expression
> makes it's way into the language, I would like to contribute my humble
> opinion to the syntax arguments.

[ several excellent points snipped ]

> Just my 2 cents, for what it's worth.

Thank you, Don... that was worth far more than 2 cents... it comes to
slightly different conclusions thatn _I_ was beginning to reach, but was
one of the most insightful and useful posts yet.

-- Michael Chermside


t...@cs.ucr.edu

unread,
Sep 18, 2001, 12:46:20 PM9/18/01
to
Michael Chermside <mch...@destiny.com> wrote:
:> What do you think about this idiom?

I have a similar objection to the syntax:

cond( <exp1>, lambda:<exp2>, lambda:<exp3> )

Moreover it doesn't scale up to multiple tests very well:

cond( <exp>, lambda:<exp>, lambda:cond( <exp>, lambda:<exp>, lambda:<exp> ) )

or stacked/indented version thereof.

Tom Payne

James_...@i2.com

unread,
Sep 19, 2001, 2:29:15 PM9/19/01
to pytho...@python.org

Tom Payne wrote:
>I have a similar objection to the syntax:
>
> cond( <exp1>, lambda:<exp2>, lambda:<exp3> )
>
>Moreover it doesn't scale up to multiple tests very well:
>
> cond( <exp>, lambda:<exp>, lambda:cond( <exp>, lambda:<exp>, lambda:<exp>
) )
>
>or stacked/indented version thereof.

... which is perhaps mitigated by the fact that nested conditional
expressions is probably not a great idea for readability in any case.

Jim

t...@cs.ucr.edu

unread,
Sep 19, 2001, 5:02:59 PM9/19/01
to
James_...@i2.com wrote:

To me,

count = 1 if by_land() else
2 if by_sea() else
0

is clearer than

if by_land():
count = 1
elif by_sea():
count = 2
else:
count = 0

By contrast,

count = cond( by_land(), lambda: 1,
cond( by_sea(), lambda: 2,
lambda: 0
))

is indeed "not a great idea for readability."

Tom Payne

James_...@i2.com

unread,
Sep 20, 2001, 1:58:07 PM9/20/01
to pytho...@python.org

Tom Payne wrote:
>To me,
>
> count = 1 if by_land() else
> 2 if by_sea() else
> 0
>
>is clearer than
>
> if by_land():
> count = 1
> elif by_sea():
> count = 2
> else:
> count = 0

On the other hand, it's hard to make the case that the latter is *unclear*.
And it's already there, just waiting to be used. ;-)

Jim


t...@cs.ucr.edu

unread,
Sep 20, 2001, 7:25:42 PM9/20/01
to
James_...@i2.com wrote:

But it's not an expression.

Tom Payne


0 new messages