[Python-Dev] Switch statement

Guido van Rossum guido at python.org
Wed Jun 21 18:55:00 CEST 2006

On 6/21/06, Phillip J. Eby <pje at telecommunity.com> wrote:
> At 09:16 AM 6/21/2006 -0700, Guido van Rossum wrote:
> >After thinking about it a bit I think that if it's not immediately
> >contained in a function, it should be implemented as alternative
> >syntax for an if/elif chain.
> That worries me a little.  Suppose I write a one-off script like this:
> for line in sys.stdin:
>      words = line.split()
>      if words:
>          switch words[0]:
>              case "foo": blah
>              case words[-1]: print "mirror image!"

Why would you write a script like that? If you've learned the
"idiomatic" use of a switch statement first, that would never occur to
you. If you're totally clueless, I don't really care that much.

> Then, if I later move the switch into a function, it's not going to mean
> the same thing any more.

And it will be a clear compile-time warning because in the refactored
version you'd be attempting to use a local variable in a case.

> If the values are frozen at first use or
> definition time (which are the same thing for module-level code), then I'll
> find the lurking bug sooner.

Or not, depending on how easily the misbehavior is spotted from a
cursory glance at the output.

> OTOH, breaking it sooner doesn't seem like such a great idea either; seems
> like a recipe for a newbie-FAQ, actually.  ISTM that the only sane way to
> deal with this would be to ban the switch statement at module level, which
> then seems to be an argument for not including the switch statement at all.  :(

I don't understand this line of reasoning. The semantics I propose are
totally well-defined.

> I suppose the other possibility would be to require at compilation time
> that a case expression include only non-local variables.  That would mean
> that you couldn't use *any* variables in a case expression at module-level
> switch, but wording the error message for that to not be misleading might
> be tricky.

That seems overly restrictive given that I expect *most* cases to use
named constants, not literals.

> I suppose an error message for the above could simply point to the fact
> that 'words' is being rebound in the current scope, and thus can't be
> considered a constant.  This is only an error at the top-level if the
> switch appears in a loop, and the variable is rebound somewhere within that
> loop or is rebound more than once in the module as a whole (including
> 'global' assignments in functions).

Let's not focus on the error message. I think your assumption that
every switch at the global level ought to be able to be moved into a
function and work the same way is not a particularly important

(As a compromise, a switch at the global level with only literal cases
could be efficiently optimized. This should include "compile-time
constant expressions".)

BTW a switch in a class should be treated the same as a global switch.
But what about a switch in a class in a function?

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

More information about the Python-Dev mailing list