[Python-Dev] Switch statement

Guido van Rossum guido at python.org
Wed Jun 21 22:16:59 CEST 2006

On 6/21/06, Phillip J. Eby <pje at telecommunity.com> wrote:
> >But that's not the discerning rule in my mind; the rule is, how to
> >define "at function definition time".
> Waaaaa!  (i.e., my head hurts again :)

Um, wasn't this your proposal (to freeze the case expressions at
function definition time)?

> > > I think the top-level is the only thing that really needs a special case
> > > vs. the general "error if you use a local variable in the expression" rule.
> >
> >To the contrary, at the top level my preferred semantics don't care
> >because they don't use a hash.
> >
> >The strict rules about locals apply when it occurs inside a function,
> >since then we eval the case expressions at function definition time,
> >when the locals are undefined. This would normally be good enough, but
> >I worry (a bit) about this case:
> >
> >   y = 12
> >   def foo(x, y):
> >     switch x:
> >     case y: print "something"
> >
> >which to the untrained observer (I care about untrained readers much
> >more than about untrained writers!) looks like it would print
> >something if x equals y, the argument, while in fact it prints
> >something if x equals 12.
> I was thinking this should be rejected due to a local being in the 'case'
> expression.

Me too. I guess I was just pointing out that "just" evaluating it in
the global scope would not give an error, just like this is valid (but

y = 12
def foo(y=y):
  print y
y = 13
foo()  # prints 12

> > > Actually, it might be simpler just to always reject local variables -- even
> > > at the top-level -- and be done with it.
> >
> >Can't because locals at the top-level are also globals.
> But you could also just use literals, and the behavior would then be
> consistent.  But I'm neither so enamored of that solution nor so against
> if/elif behavior that I care to argue further.

Yeah, but if you have names for your constants it would be a shame if
you couldn't use them because they happen to be defined in the same

> One minor point, though: what happens if we generate an if/elif for the
> switch, and there's a repeated case value?  The advantage of still using
> the hash-based code at the top level is that you still get an error for
> duplicating keys.

Sure. But the downside is that it's now actually *slower* than the
if/elif version, because it must evaluate all the case expressions.

> Ugh.  It still seems like the simplest implementation is to say that the
> lookup table is built "at first use" and that the case expressions may not
> refer to variables that are known to be bound in the current scope, or
> rebound in the case of the top level.  So the 'case y' example would be a
> compile-time error, as would my silly "words" example.  But code that only
> used "constants" at the top level would work.

I don't like "first use" because it seems to invite tricks.

The 'case y' example can be flagged as a compile time error with
enough compile-time analysis (we *know* all the locals after all).

IMO your silly words example should just pass (at the global level);
it's silly but not evil, and it's totally clear what it does if it
does anything at all (using the if/elif translation semantics; not
using the first-use semantics). That it doesn't refactor cleanly into
a function body isn't enough reason to forbid it.

I feel some kind of rule of thumb coming up regarding language design,
but I'm having a hard time saying it clearly. It's something about
making commonly written idioms easy to understand even for people
without a full understanding of the language, so that (a) people
generalizing from a few examples without too much help or prior
understanding won't go too far off, and (b) people who *do* care to
read and understand the language spec can always clearly find out wat
any particular thing means and know the pitfalls.

An example is assignment. Python lets you do things like

  x = 42
  y = x

and it all sounds completely reasonable. But Fortran/C/C++ programmers
beware, although the syntax is familiar, this is really a name-binding
statement, not a value-copying statement.

There are many other examples. Function and class definition for
example (look like definitions but are run-time constructs unlike in
most other languages). Etc.

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

More information about the Python-Dev mailing list