[Python-Dev] PEP 3103: A Switch/Case Statement

Guido van Rossum guido at python.org
Tue Jun 27 21:11:50 CEST 2006


On 6/27/06, Ron Adam <rrr at ronadam.com> wrote:
> Guido van Rossum wrote:
> > It looks like your proposal is to change switch into a command that
> > defines a function of one parameter. Instead of the "do <expression>
> > in <switch>" call you could just call the switch -- no new syntax
> > needed. Your example above would be
> >
> >  for choice in data:
> >    name(choice)          # 'name' is the switch's name
>
> I thought of using a function call so it would be more like using a
> generator, but also ruled it out because it does create a new scope and
> I think closures may complicate it or it would require also passing all
> the names needed for each case which would get old quick if it is
> required every time.  One of the things I want to be able to avoid in
> dict based dispatching for cases with only one or two lines of code.
>
> So my intent was that it use the local scope and not use the function
> call signature which implies a new scope to the reader and a returned
> value, thus the 'do choice in name' calling form.  No returned value is
> needed because it has full access to local name space.
>
> for example you wouldn't write...
>
>     return if x: 42 else: 84
>
> but would instead...
>
>     if x:
>       y = 42
>     else:
>       y = 84
>     return y
>
>
> The 'do' is used in the same context an 'if' is used.
>
>     switch a:
>       True: y=42
>       else: y=84
>
>     do x in a:
>     return y

Ah, I see.

> > However, early on in the switch discussion it was agreed that switch,
> > like if/elif, should  not create a new scope; it should just be a
> > control flow statement sharing the surrounding scope. The switch as
> > function definition would require the use of globals.
> >
> > Also, it would make sense if a switch could be a method instead of a
> > function.
>
> There's no reason why it couldn't be put "in" a method.  If the switch
> uses the surrounding name space you have that flexibility.  I'm not sure
> if the select definition could be put in the body of a class and have
> the do's in a method. That would be like having an if in the body of the
> class and the else to it in a method, so I would think it wouldn't be
> allowed.  So they both would need to be in the same name space and the
> select will always need to be defined before the 'do' is executed.
>
> > I realize that by proposing a new invocation syntax (do ... in ...)
> > you might have intended some other kind of interaction between the
> > switch and the surrounding scope. but exactly what you're proposing
> > isn't very clear from your examples, since you don't have any example
> > code in the case suites, just "...".
>
> What was intended probably would be more closely related to constructing
> a switch with BASICS gosub command.

I understand now.

But I have a question: if I write

  for i in range(10):
    switch S:
      case i: print 42

(i.e. the switch is *inside* the for loop) does the switch get defined
10 times (with 10 different case values!) or not?

>     one:              # in basic these do not have their own scope
>       print 'one'
>       return          # return from subroutine not function here
>
>     two:
>       print 'two'
>       return
>
>     three:
>       print 'three'
>       return
>
>     data = ('one', 'two', 'three')
>     for choice in data:
>         if choice == 'one': gosub one
>         elif choice == 'two': gosub two
>         elif choice == 'three': gosub three
>
>
> Which would be better expressed as..
>
>
>     switch choices:
>         'one':  print 'one'
>         'two':  print 'two'
>         'three':  print 'three'
>
>     for choice in ('one', 'two', 'three'):
>         do choice in choices

I'm not sure I like the idea of using BASIC as a way to explain Python
functionality... :-)

> Each case label expression would be evaluated when the switch block is
> executed, ie... in order it appears in the program, but the code for
> each case would be skipped until a (do choice in choices) line. Each
> switch case block would not fall through but return to the next line
> after the 'do' line by default.
>
> The whole thing could be put in a separate function or method if it's
> desired to get the single function call form you suggested along with a
> separate name space.
>
>     def switcher(choice):
>         switcher roo:
>            1: a = 42
>            42: a = 1
>            else: raise ValueError
>
>         do choice in switcher:
>         return a
>
>     switcher(1)   ->   42
>     switcher(42)  ->   1
>     switcher(100) ->   raises exception

I'm still unclear on when you propose the case expressions to be
evaluated. Each time the "switch" statement is encountered? That would
be the most natural given the rest of your explanation. But then a
switch inside a function that references globally defined constants
would be re-evalulated each time the function is called; much of the
discussion here is focused on trying to reduce the number of times the
switch cases are evaluated to once per program invocation or once per
function *definition*.

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


More information about the Python-Dev mailing list