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

Piet van Oostrum piet at
Sat Feb 8 18:03:43 CET 2003

>>>>> Guido van Rossum <guido at> (GvR) wrote:

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

I think the if-then-else expression are really necessary. All the proposed
alternatives are UGLY, and python should discourage ugliness (this is one of
its major features!).
So I am in favor.

GvR>     The proposed syntax is as follows:

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

UGLY and counter-intuitive.

GvR> Alternatives

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

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

If we take '->' instead of 'then' then we don't need a new keyword. The
combination '->' is illegal in current Python.

So the construction would be:
         if <condition> -> <expression1> else <expression2>

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

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

GvR>     could be an syntactically correct expression statement, but starts
GvR>     with 'if', which makes the parser believe it is the start of an
GvR>     'if' statement.  To resolve this, the syntax would have to require
GvR>     parentheses, which makes it uglier.  

The ambiguity can be resolved by making some changes to the grammar (no
language change other than the if expression). First split <expr_stmt> into
<NIFexpr_stmt> and <IFexpr_stmt> where the first one cannot start with 'if'
and the second does start with 'if'. This requires a few other
nonterminals also to be split. Then merge the <IFexpr_stmt> with <if_stmt>,
substitute some nonterminals, and factor out the 'if' test part.

Here is a first try of the affected grammar rules:

 expr_stmt: NIFtestlist (augassign testlist | ('=' testlist)*)

 if_stmt: 'if' test (':' suite ('elif' test ':' suite)* ['else' ':' suite] |
          '->' or_test 'else' or_test (',' test)* [',']
          (augassign testlist | ('=' testlist)*))

 test: NIFtest | IFtest
 NIFtest: or_test | lambdef
 IFtest: 'if' test '->' or_test 'else' or_test
 or_test: and_test ('or' and_test)*

 testlist: NIFtestlist | IFtestlist
 NIFtestlist: NIFtest (',' test)* [',']
 IFtestlist: IFtest (',' test)* [',']

Piet van Oostrum <piet at>
Private email: P.van.Oostrum at

More information about the Python-list mailing list