[Python-checkins] python/nondist/peps pep-0308.txt,1.9,1.10
rhettinger@users.sourceforge.net
rhettinger@users.sourceforge.net
Mon, 10 Feb 2003 21:43:59 -0800
Update of /cvsroot/python/python/nondist/peps
In directory sc8-pr-cvs1:/tmp/cvs-serv19656
Modified Files:
pep-0308.txt
Log Message:
Updated the PEP for GvR.
* Out of order evaluation is out of favor.
* So are ideas that do not provide for short-circuiting.
* (if <condition>: <expression1> else: <condition2>) is in vogue.
* <condition> ?? <expression1> || <expression2> is a new contender.
* cond(<condition>, <expression1>, <condition2>) is viable if implemented
as a keyword and has short-circuit behavior.
* Added a summary of a few ideas from the last couple hundred posts
from comp.lang.python.
Index: pep-0308.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/peps/pep-0308.txt,v
retrieving revision 1.9
retrieving revision 1.10
diff -C2 -d -r1.9 -r1.10
*** pep-0308.txt 9 Feb 2003 05:12:54 -0000 1.9
--- pep-0308.txt 11 Feb 2003 05:43:56 -0000 1.10
***************
*** 3,7 ****
Version: $Revision$
Last-Modified: $Date$
! Author: Guido van Rossum
Status: Draft
Type: Standards Track
--- 3,7 ----
Version: $Revision$
Last-Modified: $Date$
! Author: Guido van Rossum and Raymond D. Hettinger
Status: Draft
Type: Standards Track
***************
*** 28,32 ****
The proposed syntax is as follows:
! <expression1> if <condition> else <expression2>
This is evaluated like this:
--- 28,33 ----
The proposed syntax is as follows:
! (if <condition>: <expression1> else: <expression2>)
!
This is evaluated like this:
***************
*** 41,63 ****
Note that at most one of <expression1> and <expression2> 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:
--- 42,49 ----
Note that at most one of <expression1> and <expression2> is
! evaluated. This is called a "short-circuit expression"; it is similar
to the way the second operand of 'and' / 'or' is only evaluated if
the first operand is true / false.
Note: a common way to emulate an if-then-else expression is:
***************
*** 72,82 ****
Alternatives
Many C-derived languages use this syntax:
<condition> ? <expression1> : <expression2>
! 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.
--- 58,77 ----
Alternatives
+ The original version of this PEP proposed the following syntax:
+
+ <expression1> if <condition> else <expression2>
+
+ The out-of-order arrangement was found to be too uncomfortable
+ for many of participants in the discussion.
+
+ ---
+
Many C-derived languages use this syntax:
<condition> ? <expression1> : <expression2>
! Eric Raymond even implemented this. The BDFL rejected 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.
***************
*** 94,168 ****
---
! If we could live with adding a new keyword, we could use:
! if <condition> then <expression1> else <expression2>
! 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 <condition> : <expression1> else <expression2>
! 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 <condition> : <expression1> else: <expression2>
! 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':
! <expression1> when <condition> else <expression2>
! 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).
--- 89,232 ----
---
! Raymond Hettinger proposed a variant that removes the
! arbitrariness:
! <condition> ?? <expression1> || <expression2>
! The ?? and || are not arbitrary as they strongly suggest testing
! and alternation. Another merit is that that existing operators
! are not overloaded. Having two characters at each step also
! helps visually separate the subordinate expressions. Alas,
! the BDFL prefers the proposed syntax and considers this as
! alternative number one.
! ---
! 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.
! Summary of the Current State of the Discussion
! Groups are falling into one of five camps:
! 1. Adopt a ternary operator built using punctuation characters.
! It would look something like:
! <condition> ?? <expression1> || <expression2>
! 2. Adopt a ternary operator built using existing keywords.
! The proposal listed above is the leading example.
! 3. Adopt a ternary operator built using a new keyword.
! The leading contender looks like this:
! cond(<condition>, <expression1>, <expression2>)
! 4. Adopt a function without short-circuit behavior:
! cond(<condition>, <expression1>, <expression2>)
! 5. Do nothing.
+ The first two positions are relatively similar.
! Some find that any form of punctuation makes the language more
! cryptic. Others find that punctuation style is appropriate
! for expressions rather than statements and helps avoid a COBOL
! style: 3 plus 4 times 5.
! Adapting existing keywords attempts to improve on punctuation
! through explicit meaning and a more tidy appearance. The downside
! is some loss of the economy-of-expression provided by punctuation
! operators. The other downside is that it creates some degree of
! confusion between the two meanings and two usages of the keywords.
! The third form introduces a new keyword and arranges the arguments
! separated by commas. Adding a new keyword is to be generally avoided.
! But the form is clear, short, and direct. There is a possible
! confusion with function syntax which implies that all the arguments
! are evaluated rather than short-circuited. This idea was presented
! by the BDFL and should be considered a contender for the final vote.
! The exact keyword is still an open question. One proposal was iif(),
! but it looks like a typo and can be confused with if-and-only-if
! which has a different, well-defined mathematical meaning.
! The fourth position is much more conservative. Adding a new
! function, cond(), is trivially easy to implement and fits easily
! within the existing python model. Users of older versions of
! Python will find it trivial to simulate. The downside is that
! it does not provide the sought-after short-circuit
! evaluation (see the discussion below on the need for this).
! The bigger downside is that the BDFL opposes *any* solution that
! does not provide short circuit behavior.
! The last position is doing nothing. Arguments in favor include
! keeping the language simple and concise; maintaining backwards
! compatibility; and that any every use cases can already be already
! expressed in terms of "if" and "else". Lambda expressions are
! an exception as they require the conditional to be factored out
! into a separate function definition.
! The arguments against doing nothing are that the other choices
! allow greater economy of expression and that current practices
! show a propensity for erroneous uses of "and", "or", or one their
! more complex, visually unappealing workarounds.
! It should also be mentioned that most supporters of any of the
! first four positions do not want an imperfect solution
! and would sooner have no change than create a wart to attain
! their desired functionality.
!
! Short-Circuit Behavior
!
! The principal difference between the ternary operator
! and the cond() function is that the latter provides an expression
! form but does not provide short-circuit evaluation.
!
! Short-circuit evaluation is desirable on three occasions:
!
! 1. When an expression has side-effects
! 2. When one or both of the expressions are resource intensive
! 3. When the condition serves as a guard for the validity of the
! expression.
!
! # Example where all three reasons apply
! data = isinstance(source, file) ?? source.readlines()
! || source.split()
!
! 1. readlines() moves the file pointer
! 2. for long sources, both alternatives take time
! 3. split() is only valid for strings and readlines() is only
! valid for file objects.
!
! Supporters of the cond() function point-out that the need for
! short-circuit evaluation is rare. Scanning through existing
! code directories, they found that if/else did not occur often;
! and of those only a few contained expressions that could be
! helped by cond() or a ternary operator; and that most of those
! had no need for short-circuit evaluation. Hence, cond() would
! suffice for most needs and would spare efforts to alter the
! syntax of the language.
!
! More supporting evidence comes from scans of C code
! bases which show that its ternary operator used very rarely
! (as a percentage of lines of code).
!
! A counter point to that analysis is that the availability
! of a ternary operator helped the programmer in every case
! because it spared the need to search for side-effects.
! Further, it would preclude errors arising from distant
! modifications which introduce side-effects. The latter case
! has become more of a reality with the advent of properties
! where even attribute access can be given side-effects.
!
! Still, the point is moot since the BDFL opposes solutions
! which do not provide short-circuit behavior.