[Python-Dev] Simple Switch statement (original) (raw)

Ron Adam rrr at ronadam.com
Sun Jun 25 04:06:33 CEST 2006


Raymond Hettinger wrote:

From what I can see, almost everyone wants a switch statement, though perhaps for different reasons. The main points of contention are 1) a non-ambiguous syntax for assigning multiple cases to a single block of code, 2) how to compile variables as constants in a case statement, and 3) handling overlapping cases. Here's a simple approach that will provide most of the benefit without trying to overdo it:

Looks good to me.

switch f(x): # any expression is allowable here but raises an exception if the result is not hashable case 1: g() # matches when f(x)==1 case 2,3 : h() # matches when f(x) in (2,3) case 1: i() # won't ever match because the first case 1 wins case (4,5), 6: j() # matches when f(x) in ((4,5), 6) case "bingo": k() # matches when f(x) in ("bingo",) default: l() # matches if nothing else does

Though implemented as a hash table, this would execute as if written: fx = f(x) hash(fx) if fx in (1,): g() elif fx in (2,3): h() elif fx in (1,): i() elif fx in ((4,5), 6): j() elif fx in ("bingo",): k() else: l() The result of f(x) should be hashable or an exception is raised. Cases values must be ints, strings, or tuples of ints or strings. No expressions are allowed in cases. Since a hash table is used, the fx value must support hash and eq, but not expect multiple eq tests as in the elif version. I've bypassed the constantification issue. The comes-up throughout Python and is not unique to the switch statement. If someone wants a "static" or "const" declaration, it should be evaluated separately on its own merits.

Yes, I agree.

When the constants are mapped to integers instead of strings, it is no burden to supply a reverse mapping like we already do in opcode.py. This commonplace setup also makes it easy to write fast switch-case suites:

from opcode import opmap def calcjumpstatistics(f): reljumps = absjumps = 0 for opcode, oparg in gencodes(f.funccode.cocode): switch opmap[opcode]: case 'JUMPFORWARD', 'JUMPIFFALSE', 'JUMPIFTRUE': reljumps +=1 case 'JUMPABSOLUTE', 'CONTINUELOOP': absjumps += 1 . . . So, that is it, my proposal for simple switch statements with a straight-forward implementation, fast execution, simply explained behavior, and applicability to to the most important use cases.

Just what I was looking for! +1

I happen to like simple modular code that when combined is more than either alone, which I believe is the case here when using mappings with switches. This type of synergy is common in python and I have no problem using a separate lookup map to do early and/or more complex evaluations for cases.

Cheers, Ron

Raymond

P.S. For the sre case, we get a great benefit from using strings. Since they are all interned at compile time and have their hash values computed no more than once, the dispatch table will never have to actually calculate a hash and the full string comparison will be bypassed because "identity implies equality". That's nice. The code will execute clean and fast. AND we get readability improvements too. Not bad.



More information about the Python-Dev mailing list