For review: PEP 308 - If-then-else expression
Piet van Oostrum
piet at cs.uu.nl
Sat Feb 8 18:03:43 CET 2003
>>>>> Guido van Rossum <guido at python.org> (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 c.l.py 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
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> 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 cs.uu.nl>
URL: http://www.cs.uu.nl/~piet [PGP]
Private email: P.van.Oostrum at hccnet.nl
More information about the Python-list