diff --git a/pep-0275.txt b/pep-0275.txt index 232dad40a..71436911f 100644 --- a/pep-0275.txt +++ b/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": @@ -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