New revision. Incoporates a lot of comments from python-dev.

This commit is contained in:
Marc-André Lemburg 2001-11-23 10:10:35 +00:00
parent 152dcf535d
commit a281f916b7
1 changed files with 64 additions and 34 deletions

View File

@ -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":
@ -281,9 +297,18 @@ Solutions 2: Adding a switch statement to Python
SUITE in ("seventh",):
... print "done"
else: break # out of loop!
SUITE else:
print "middle state"
state = next_state(state)
SUITE else:
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
@ -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