New revision. Incoporates a lot of comments from python-dev.
This commit is contained in:
parent
152dcf535d
commit
a281f916b7
92
pep-0275.txt
92
pep-0275.txt
|
@ -1,7 +1,7 @@
|
|||
PEP: 0275
|
||||
Title: Switching on Multiple Values
|
||||
Version: $Revision$
|
||||
Author: mal@lemburg.com (Marc-Andre Lemburg)
|
||||
Author: mal@lemburg.com (Marc-André Lemburg)
|
||||
Status: Draft
|
||||
Type: Standards Track
|
||||
Python-Version: 2.3
|
||||
|
@ -73,32 +73,14 @@ Proposed Solutions
|
|||
involve some run-time overhead to assure that the switching
|
||||
variable is immutable and hashable.
|
||||
|
||||
Both solutions use a dictionary lookup to find the right
|
||||
jump location, so they both share the same problem space in
|
||||
terms of requiring that both the switch variable and the
|
||||
constants need to be compatible to the dictionary implementation
|
||||
(hashable, comparable, a==b => hash(a)==hash(b)).
|
||||
|
||||
Solution 1: Optimizing if-elif-else
|
||||
|
||||
XXX This section currently only sketches the design.
|
||||
|
||||
Issues:
|
||||
|
||||
The new optimization should not change the current Python
|
||||
semantics (by reducing the number of __cmp__ calls and adding
|
||||
__hash__ calls in if-elif-else constructs which are affected
|
||||
by the optimiztation). To assure this, switching can only
|
||||
safely be implemented either if a "from __future__" style
|
||||
flag is used, or the switching variable is one of the builtin
|
||||
immutable types: int, float, string, unicode, etc. (not
|
||||
subtypes, since it's not clear whether these are still
|
||||
immutable or not)
|
||||
|
||||
To prevent post-modifications of the jump-table dictionary
|
||||
(which could be used to reach protected code), the jump-table
|
||||
will have to be a read-only type (e.g. a read-only
|
||||
dictionary).
|
||||
|
||||
The optimization should only be used for if-elif-else
|
||||
constructs which have a minimum number of n cases (where n is
|
||||
a number which has yet to be defined depending on performance
|
||||
tests).
|
||||
|
||||
Implementation:
|
||||
|
||||
It should be possible for the compiler to detect an
|
||||
|
@ -127,11 +109,31 @@ Solution 1: Optimizing if-elif-else
|
|||
SWITCH opcode and procedding with the usual if-elif-else byte
|
||||
code stream.
|
||||
|
||||
Solutions 2: Adding a switch statement to Python
|
||||
Issues:
|
||||
|
||||
XXX This section currently only sketches the design.
|
||||
The new optimization should not change the current Python
|
||||
semantics (by reducing the number of __cmp__ calls and adding
|
||||
__hash__ calls in if-elif-else constructs which are affected
|
||||
by the optimiztation). To assure this, switching can only
|
||||
safely be implemented either if a "from __future__" style
|
||||
flag is used, or the switching variable is one of the builtin
|
||||
immutable types: int, float, string, unicode, etc. (not
|
||||
subtypes, since it's not clear whether these are still
|
||||
immutable or not)
|
||||
|
||||
Syntax:
|
||||
To prevent post-modifications of the jump-table dictionary
|
||||
(which could be used to reach protected code), the jump-table
|
||||
will have to be a read-only type (e.g. a read-only
|
||||
dictionary).
|
||||
|
||||
The optimization should only be used for if-elif-else
|
||||
constructs which have a minimum number of n cases (where n is
|
||||
a number which has yet to be defined depending on performance
|
||||
tests).
|
||||
|
||||
Solution 2: Adding a switch statement to Python
|
||||
|
||||
New Syntax:
|
||||
|
||||
switch EXPR:
|
||||
case CONSTANT:
|
||||
|
@ -145,7 +147,14 @@ Solutions 2: Adding a switch statement to Python
|
|||
(modulo indentation variations)
|
||||
|
||||
The "else" part is optional. If no else part is given and
|
||||
none of the defined cases matches, a ValueError is raised.
|
||||
none of the defined cases matches, no action is taken and
|
||||
the switch statement is ignored. This is in line with the
|
||||
current if-behaviour. A user who wants to signal this
|
||||
situation using an exception can define an else-branch
|
||||
which then implements the intended action.
|
||||
|
||||
Note that the constants need not be all of the same type, but
|
||||
they should be comparable to the type of the switch variable.
|
||||
|
||||
Implementation:
|
||||
|
||||
|
@ -194,6 +203,9 @@ Solutions 2: Adding a switch statement to Python
|
|||
Where the 'SWITCH' opcode would jump to 14, 22, 30 or 38
|
||||
depending on 'x'.
|
||||
|
||||
Thomas Wouters has written a patch which demonstrates the
|
||||
above. You can download it from [1].
|
||||
|
||||
Issues:
|
||||
|
||||
The switch statement should not implement fall-through
|
||||
|
@ -238,13 +250,17 @@ Solutions 2: Adding a switch statement to Python
|
|||
else:
|
||||
SUITE
|
||||
|
||||
The switch statement could be extended to allow tuples of
|
||||
The switch statement could be extended to allow multiple
|
||||
values for one section (e.g. case 'a', 'b', 'c': ...). Another
|
||||
proposed extension would allow ranges of values (e.g. case
|
||||
10..14: ...). These should probably be post-poned, but already
|
||||
kept in mind when designing and implementing a first version.
|
||||
|
||||
Examples:
|
||||
Examples:
|
||||
|
||||
The following examples all use a new syntax as proposed by
|
||||
solution 2. However, all of these examples would work with
|
||||
solution 1 as well.
|
||||
|
||||
switch EXPR: switch x:
|
||||
case CONSTANT: case "first":
|
||||
|
@ -285,6 +301,15 @@ Solutions 2: Adding a switch statement to Python
|
|||
print "middle state"
|
||||
state = next_state(state)
|
||||
|
||||
Here's another nice application found by Jack Jansen (switching
|
||||
on argument types):
|
||||
|
||||
switch type(x).__name__:
|
||||
case 'int':
|
||||
SUITE
|
||||
case 'string':
|
||||
SUITE
|
||||
|
||||
Scope
|
||||
|
||||
XXX Explain "from __future__ import switch"
|
||||
|
@ -296,6 +321,11 @@ Credits
|
|||
Skip Montanaro (dispatching ideas, examples)
|
||||
Donald Beaudry (switch syntax)
|
||||
Greg Ewing (switch syntax)
|
||||
Jack Jansen (type switching examples)
|
||||
|
||||
References
|
||||
|
||||
[1] https://sourceforge.net/tracker/index.php?func=detail&aid=481118&group_id=5470&atid=305470
|
||||
|
||||
Copyright
|
||||
|
||||
|
|
Loading…
Reference in New Issue