[Python-Dev] conditional expressions?

Guido van Rossum guido@python.org
Mon, 15 Oct 2001 17:42:39 -0400


> [Guido]
> > ...
> > Some examples where no parentheses are needed (note that a comma binds
> > less tight than a conditional expression -- same as for lambda):
> >
> >     x = if 1 then 2 else 3, y

[Tim]
> Also
> 
>     x = if 1 then 2 else 3,
> 
> which sets x to the singleton tuple (2,).  This is an old potential
> confusion, though, much the same as the current
> 
>     x = 2 or 3,
> 
> (which also sets x to (2,)).

These don't bother me any more than

    x = 2,

does.

> > ...
> > Some examples where parentheses *are* required:
> >
> >     (if 1 then 2 else 3) + 4
> 
> But that's because it's a top-level expression beginning with "if", not
> because of the "+", right?  In the patched Python, this works fine:
> 
> >>> x = if 0 then 2 else 3 + 4
> >>> x
> 7
> >>>

But it groups differently: the 'else' part is '3 + 4' here.  Try 'if
1'. :-)

> OTOH, these seem odd:
> 
> >>> 4 + if 1 then 2 else 3
>   File "<stdin>", line 1
>     4 + if 1 then 2 else 3
>          ^
> SyntaxError: invalid syntax

That's too much work for the parser to get right.  And you'd get
anomalies like

    3 * if 1 then 2 else 3 + 4

-- how should this group?

> >>> x = 4 + if 1 then 2 else 3
>   File "<stdin>", line 1
>     x = 4 + if 1 then 2 else 3
>              ^
> SyntaxError: invalid syntax
> >>>
> 
> I say "odd" because there's no question about what they mean.

Only because the examples are so simply.

> >     a[(if i then 2 else 3) : 4]
> >
> > In some situations I'm not sure what's right; The un-parenthesized
> > form looks weird although it's not neede to avoid ambiguity:
> >
> >     if (if 1 then 2 else 3): pass
> >     print (if 1 then 2 else 3)
> 
> OTOH,
> 
>     print >> sys.stderr, if 1 then 2 else 3
> and
>     print 4, if 1 then 2 else 3
> 
> don't look particularly weird but also raise SyntaxError.
> 
> As a matter of taste, I was most surprised by the
> 
>     4 + if 1 then 2 else 3
> 
> examples.

They act the same as lambda in this respect.

Because the conditional *ends* in something that "pulls in" all
following binary operators and their operands until it hits a ")", 
I find it safer not to let it accept an operator at the front.

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