[Python-Dev] Switch statement

Guido van Rossum guido at python.org
Thu Jun 22 19:44:52 CEST 2006

On 6/22/06, Phillip J. Eby <pje at telecommunity.com> wrote:
> At 09:37 AM 6/22/2006 -0700, Guido van Rossum wrote:
> >On 6/22/06, Phillip J. Eby <pje at telecommunity.com> wrote:
> > > This hypothetical "const" would be a *statement*,
> > > executed like any other statement.  It binds a name to a value -- and
> > > produces an error if the value changes.  The compiler doesn't need to know
> > > what it evaluates to at runtime; that's what LOAD_NAME or LOAD_DEREF are
> > > for.  ;)
> >
> >Please think this through more. How do you implement the "produces an
> >error if the value changes" part? Is the const property you're
> >thinking of part of the name or of the object it refers to?
> >
> >The only way I can see it work is if const-ness is a compile-time
> >property of names, just like global. But that requires too much
> >repetition when a constant is imported.
> Right; MAL pointed that out in the message I was replying to, and I
> conceded his point.  Of course, if you consider constness to be an implicit
> property of imported names that aren't rebound, the repetition problem goes
> away.

Um, technically names are never imported, only objects. Suppose module
A defines const X = 1, and module B imports A. How does the compiler
know that A.X is a constant?

I still don't see how const declarations can be made to work, and
unless you can show me how I don't see how they can help.

> And if you then require all "case" expressions to be either literals or
> constant names, we can also duck the "when does the expression get
> evaluated?" question.  The obvious answer is that it's evaluated wherever
> you bound the name, and the compiler can either optimize the switch
> statement (or not), depending on where the assignment took place.

I don't understand what you're proposing. In particular I don't
understand what you mean by "wherever you bound the name".

So (evading the import problem for a moment) suppose we have

const T = int(time.time())

def foo(x):
  switch x:
    case T: print "Yes"
    else: print "No"

Do you consider that an optimizable switch or not?

> A switch
> that's in a loop or a function call can only be optimized if all its
> constants are declared outside the loop or function body; otherwise it
> degrades to an if/elif chain.

What do you mean by a switch in a function call? Syntactically that
makes no sense. Do you mean in a function definition?

I think you're trying to give a heuristic here for when it's likely
that the switch will be executed multiple times with all cases having
the same values (so the optimized dict can be reused).

I'm afraid this is going to cause problems with predictability. Also,
if it degenerates to an if/elif chain, does it still require the
switch expression to be hashable?

> There's actually an in-between possibility, too: you could generate if's
> for constants declared in the loop or function body, and use a dictionary
> for any literals or constants declared outside the loop or function
> body.  The only problem that raises is the possibility of an "inner
> constant" being equal to an "outer constant", creating an ambiguity.  But
> we could just say that nearer constants take precedence over later ones, or
> force you to introduce the cases such that inner constants appear first.
> (This approach doesn't really need an explicit "const foo=bar" declaration,
> though; it just restricts cases to using names that are bound only once in
> the code of the scope they're obtained from.)

Please, think through the notion of const declarations more before
posting again. Without const declarations none of this can work and
the "at-function-definition-time" freezing is the best, because most
predictable, approach IMO.

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

More information about the Python-Dev mailing list