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

Josiah Carlson jcarlson at uci.edu
Wed Jun 28 18:41:29 CEST 2006

Talin <talin at acm.org> wrote:
> Josiah Carlson wrote:
> > Talin <talin at acm.org> wrote:
> > 
> >>My version of this is to add to Python the notion of a simple 
> >>old-fashioned subroutine - that is, a function with no arguments and no 
> >>additional scope, which can be referred to by name. For example:
> > 
> > 
> > I don't like the idea of an embedded subrutine for a few reasons.  One
> > of them is because you need to define the case -> sub mapping
> > dictionaries in each pass, you are getting no improvement in speed
> > (which is a motivating factor in this discussion).  Even worse, the
> > disconnect between case definition and dispatch makes it feel quite a
> > bit like a modified label/goto proposal.  The ultimate killer is that
> > your proposed syntax (even using def) make this construct less readable
> > than pretty much any if/elif/else chain I have ever seen.
> > 
> >  - Josiah
> The case -> sub mapping doesn't need to be defined every time - that's 
> the point, you as the programmer decide when and how to construct the 
> dictionary, rather than the language trying to guess what it is you 
> want. EIBTI.

Beautiful is better than ugly.

> You could also define the switch in an outer function that contains an 
> inner function that is called multiple times:
>     def Outer():
>        sub S1:
>           ...
>        sub S2:
>           ...
>        sub S3:
>           ...
>        dispatch = {
>           parser.IDENT: S1,
>           parser.NUMBER: S2,
>           parser.COMMENT: S3
>        }
>        def Inner( x ):
>           do dispatch[ x ]
>        return Inner

This allows direct access to a namespace that was previously read-only
from other namespaces (right now closure namespaces are read-only,
objects within them may not be). ...

> There is also the possibility of building the dict before the function 
> is run, however this requires a method of peeking into the function body 
> and extracting the definitions there. For example, suppose the 
> subroutine names were also attributes of the function object:
>     def MyFunc( x ):
>        sub upper:
>           ...
>        sub lower:
>           ...
>        sub control:
>           ...
>        sub digit:
>           ...
>        do dispatch[ x ]
>     # Lets use an array this time, for variety
>     dispatch = [
>        MyFunc.upper,
>        MyFunc.lower,
>        MyFunc.upper, # Yes, 2 and 3 are the same as 0 and 1
>        MyFunc.lower,
>        MyFunc.control,
>        MyFunc.digit,
>     ]

... One of my other desires for switch/case or its equivalent is that of
encapsulation.  Offering such access from outside or inside the function
violates what Python has currently defined as its mode of operations for

> With regards to your second and third points: sure, I freely admit that 
> this proposal is less readable than a switch statement. The question is, 
> however, is it more readable than what we have *now*? As I have 
> explained, comparing it to if/elif/else chains is unfair, because they 
> don't have equivalent performance. The real question is, is it more 
> readable than, say, a dictionary of references to individual functions; 
> and I think that there are a number of possible use cases where the 
> answer would be 'yes'.

Why is the comparison against if/elif/else unfair, regardless of speed? 
We've been comparing switch/case to if/elif/else from a speed
perspective certainly, stating that it must be faster (hopefully O(1)
rather than O(n)), but that hasn't been the only discussion.  In fact,
one of the reasons we are considering switch/case is because readability
still counts, and people coming from C/etc., are familliar with it. Some
find switch/case significantly easier to read, I don't, but I also don't
find it significantly harder to read.

On the other hand, if I found someone using sub in a bit of Python code,
I'd probably cry, then rewrite the thing using if/elif/else. If I was
fiesty, I'd probably do some branch counting and reorder the tests, but
I would never use subs.

> I think that language features should "just work" in all cases, or at 
> least all cases that are reasonable. I don't like the idea of a switch 
> statement that is hedged around with unintuitive exceptions and strange 
> corner cases.

And I don't like the idea of making my code ugly.  I would honestly
rather have no change than to have sub/def+do.

 - Josiah

More information about the Python-Dev mailing list