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 calc_jump_statistics(f): > reljumps = absjumps = 0 > for opcode, oparg in gencodes(f.func_code.co_code): > switch opmap[opcode]: > case 'JUMP_FORWARD', 'JUMP_IF_FALSE', 'JUMP_IF_TRUE': > reljumps +=1 > case 'JUMP_ABSOLUTE', 'CONTINUE_LOOP': > 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. _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com