[Python-Dev] Trinary Operators

Andrew Koenig ark@research.att.com
Thu, 6 Feb 2003 14:14:14 -0500 (EST)


>> Which implies, by the way, that parentheses shouldn't be mandatory
>> in the following context:
>> 
>> (lambda x, y, z: y if x else z)
>> 
>> Or, for that matter, in
>> 
>> (lambda x, y, z: f(x, y if x else z))

Guido> But does

Guido>     x, y if p else z

Guido> mean

Guido>     x, (y if p else z)

Guido> or

Guido>     (x, y) if p else z

Guido> ???

It should be consistent with the rest of the language.

What I'm thinking is that there are some contexts in which
precedence is irrelevant, because the context is bounded unambiguously
on each side.  For example, in

   f( <anything> )

there's no difficulty in figuring out that the <anything> ends just
before the ) that matches the (.  Similarly, in

   f( <anything>, <anything>)

there is still no difficulty because the ( , ) delimiters belong
together.

There's a slightly differnt rule for lamba, because it depends on
knowing unambiguously where the surrounding context ends.  Example:

	y = lambda x: x+1

There must be some kind of precedence rule to determine where the
lambda-expression ends, lest it be interpreted as

        y = (lambda x: x) + 1

So I see if/else as acting like lambda: If you enclose it in
parentheses, there's no ambiguity; if not, then it relies on knowing
something about the surrounding context.  Whatever the rules are
for figuring out the context should apply to if/else also.

Incidentally, that doesn't rule out making some questionable cases
ambiguous.  I note, for example, that

	    [i, i for i in range(10)]

doesn't compile, even though I can see only one plausible way of
parsing it (namely as

	    [(i, i) for i in range(10)]

), but on the other hand,

            [lambda x: i for i in range(10)]

compiles just fine (and yields a list of functions)