PEP: 308 Title: If-then-else expression Version: $Revision$ Last-Modified: $Date$ Author: Guido van Rossum Status: Draft Type: Standards Track Content-Type: text/plain Created: 7-Feb-2003 Post-History: 7-Feb-2003 Introduction Requests for an if-then-else ("ternary") expression keep coming up on comp.lang.python. This PEP contains a concrete proposal of a fairly Pythonic syntax. This is the community's one chance: if this PEP is approved with a clear majority, it will be implemented in Python 2.4. If not, the PEP will be augmented with a summary of the reasons for rejection and the subject better not come up again. While I am the author of this PEP, I am neither in favor nor against this proposal; it is up to the community to decide. If the community can't decide, I'll reject the PEP. Proposal The proposed syntax is as follows: if else This is evaluated like this: - First, is evaluated. - If is true, is evaluated and is the result of the whole thing. - If is false, is evaluated and is the result of the whole thing. Note that at most one of and is evaluated. This is called a "shortcut expression"; it is similar to the way the second operand of 'and' / 'or' is only evaluated if the first operand is true / false. To disambiguate this in the context of other operators, the "if...else" part in the middle acts like a right-associative binary operator with a priority lower than that of "or", and higher than that of "lambda". Examples of how this works out: x if C else y if D else z <==> x if C else (y if D else z) x or y if C else z <==> (x or y) if C else z x if C else y or z <==> x if C else (y or z) lambda: x if C else y <==> lambda: (x if C else y) x if C else lambda: y <==> SyntaxError x if C else y, z <==> (x if C else y), z x, y if C else z <==> x, (y if C else z) Note: a common way to emulate an if-then-else expression is: and or However, this doesn't work the same way: it returns when is false! See FAQ 4.16 for alternatives that work -- however, they are pretty ugly and require much more effort to understand. Alternatives Many C-derived languages use this syntax: ? : Eric Raymond even implemented this. I reject this for several reasons: the colon already has many uses in Python (even though it would actually not be ambiguous, because the question mark requires a matching colon); for people not used to C-derived language, it is hard to understand. --- David Ascher proposed a variant that doesn't have this problem: ? ! While cute, this suffers from the Perlish problem of using arbitrary punctuation with an arbitrary meaning; and it's no easier to understand than the ?: form. --- If we could live with adding a new keyword, we could use: if then else Apart from the problem of introducing a new keyword for a minor feature, this also suffers from ambiguity at the start of a statement; for example: if verbose then sys.stdout.write("hello\n") else None could be an syntactically correct expression statement, but starts with 'if', which makes the parser believe it is the start of an 'if' statement. To resolve this, the syntax would have to require parentheses, which makes it uglier. However, this form has the advantage of evaluating strictly from left to right (not that that is a requirement for being Pythonic -- list comprehensions don't). --- To deal with the problem of adding a new keyword, this variant has been proposed: if : else This has the same ambiguity problem as the previous one (I would even say more so), and lacks symmetry. It also begs the question why there isn't a colon after the 'else'. But this: if : else: is even more confusing because it resembles the if statement so much. (A solution that *doesn't* resemble the if statement is better IMO since it should be obvious at first glance whether we're dealing with an if expression or with an if statement. Placing the 'if' in the middle somehow satisfies this requirement.) --- Many people suggest adding a new builtin instead of extending the syntax of the language, e.g.: ifelse(condition, expression1, expression2) This won't work the way a syntax extension will because both expression1 and expression2 must be evaluated before the function is called. There's no way to short-circuit the expression evaluation. Variations It has been proposed to make the 'else' part optional. This would be a really bad idea. I showed: x = e if C to several people. They all thought that if C was false, it would leave x unchanged. So don't even think about this one! --- Another variant proposes to use 'when' instead of 'if': when else I don't see the advantage of 'when' over 'if'; it adds a new keyword which is a major extra hurdle to introduce this. I think that using a different keyword suggests that the semantics are different than those of an 'if' statement; but they really aren't (only the syntax is different). Copyright This document has been placed in the public domain. Local Variables: mode: indented-text indent-tabs-mode: nil sentence-end-double-space: t fill-column: 70 End: