[Python-Dev] Switch statement

Guido van Rossum guido at python.org
Fri Jun 23 20:37:33 CEST 2006


On 6/23/06, Eric Sumner <kd5bjo at gmail.com> wrote:
> On 6/22/06, Guido van Rossum <guido at python.org> wrote:
> > (3) A switch is implemented using a dict which is precomputed at the
> > same time its static expressions are precomputed. The switch
> > expression must be hashable. Overlap between different cases will
> > raise an exception at precomputation time.
>
> How does this interact with __contains__, __len__, and __iter__ for
> the 'case in S' statement?  Would it work with a class that only
> implements __contains__, such as a continuous range class?

No; in order to make it possible to use a single dict lookup for
dispatch, the set members are expanded into the dict key. If you have
a large contiguous range, you'll be better off (sometimes *much*
better) doing an explicit if/elif check before entering the switch.

Let me sketch a prototype for the code that builds the dict given the cases:

def build_switch(cases, globals):
  """
  Args:
    cases: [(op, expr, offset), ...]
      # op in ('==', 'in')
      # expr is a string giving an expression
      # offset is an integer offset where to jump for this case
    globals: dict used as a namespace
  """
  dispatch = {}
  for op, expr, offset in cases:
    value = eval(expr, globals)
    switch op:
      case '==':
        if value in dispatch:
          raise RuntimeError("duplicate switch case %r == %r" % (expr, value))
        dispatch[value] = offset
      case 'in':
        for val in value:
          if val in dispatch:
            raise RuntimeError("duplicate switch case %r contains %r"
% (expr, val))
          dispatch[val] = offset
  return dispatch

Of course, the real implementation would not use eval() or represent
the expressions as strings or represent all the cases as a list; the
compiler would probably generate byte code corresponding to the body
of either of the above cases for each case in the switch being
compiled. The dispatch dicts would be passed into the function object
constructor somehow. Lots of details for whoever wants to implement
this. :-)

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-Dev mailing list