[Python-Dev] Switch statement

Guido van Rossum guido at python.org
Mon Jun 19 19:35:20 CEST 2006

On 6/19/06, Raymond Hettinger <rhettinger at ewtllc.com> wrote:
> >>  A switch-statement offers only a modest readability improvement over
> >> if-elif chains.
> >
> >
> > Probably, which is why it hasn't been added yet. :-)
> >
> > But there is a definite readability improvement in that you *know*
> > that it's always the same variable that is being compared and that no
> > other conditions are snuck into some branches.
> Hmm, when I saw that "arbitrary expressions" were being proposed, I took
> that took mean that the variable would have to be repeated in the branches:
>    switch x:
>       case  x.endswith('wart'):  salicylic_acid()
>       case x.endswith('roid'):  preparation_h()
>       default:  chicken_soup()

That seems insane, since then it would be *just* different syntax for
if/elif. The example looks deceptive: surely the 'switch' expression
should allow an arbitrary expression, so the 'case' wouldn't be able
to refer to the switch part by a name unless there was syntax (or a
convention) for defining a name by which it could be referenced. I
think Perl 6 is defining a very general "matching" syntax which people
interested in this might want to study, just to see how far one can
stretch the insanity.

> > I would
> > think that it would be fine if some switches could be compiled into
> > some kind of lookup table while others would just be translated into a
> > series of if/elifs. As long as the compiler can tell the difference.
> >
> That's a worthy goal; of course, the devil is in the details.  Given:
>  switch x:
>     case 1:  one()
>     case 2:  two()
>     case 3:  three()
>     default:  too_many()
> Do we require that x be hashable so that the compiler can use a lookup
> table?

That's a good question. We could define switch/case in terms of a hash
table created by the compiler, and then raising an exception if x is
unhashable is fair game. Or we could define it in terms of successive
'==' comparisons, and then the compiler would have to create code for
a slow path in case x is unhashable. I don't think I'm in favor of
always taking the default path when x is unhashable; that would cause
some surprises if an object defines __eq__ to be equal to ints (say)
but not __hash__.

Note that we currently don't have a strong test for hashable; it's
basically "if hash(x) doesn't raise an exception" which means that we
would have to catch this exception (or perhaps only TypeError) in
order to implement the slow path for the successive-comparisons

I note that C doesn't require any particular implementation for
switch/case; there's no rule that says the numbers must fit in an
array of pointers or anything like that. So I would be careful before
we define this in terms of hash tables. OTOH the hash table semantics
don't require us to commit to a definition of hashable, which is an

How's that for a wishy-washy answer. :-)

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

More information about the Python-Dev mailing list