[Python-Dev] switch-based programming in Python

Thomas Wouters thomas@xs4all.net
Fri, 9 Nov 2001 12:10:35 +0100


On Fri, Nov 09, 2001 at 03:36:59PM +1300, Greg Ewing wrote:
> Thomas Wouters <thomas@xs4all.net>:

> >  switch EXPR:
> >  case CONSTANT:
> >      [suite]
> >  case CONSTANT:
> >      [suite]
> >  ...
> >  else:

> Looks good, except that I'd indent the cases as well, i.e.

>   switch EXPR:
>     case CONSTANT:
>       [suite]
>     case CONSTANT:
>       [suite]
>     else:
>       [suite]

> To my mind the cases are logically a subordinate part of the 
> switch statement, and the indentation should reflect that.

Hmm. Perhaps. I'm not entirely convinced but it's not big an issue.

> Some alternatives:

> Using only one keyword:

>   case EXPR:
>     CONSTANT:
>       [suite]
>     CONSTANT:
>       [suite]
>     else:
>       [suite]

Can't be done in a LL(1) parser such as Python's. (And Guido already stated
that even if we switch to a more capable parser/tokenizer, we still need to
maintain this restriction for the sake of other tools parsing Python, e.g.
IDLE.)

> Using two, but reminding one less of C:

>   case EXPR:
>     of CONSTANT:
>       [suite]
>     of CONSTANT:
>       [suite]
>     else:
>       [suite]

I've been considering this... I'm not sure I like it. The 'case' instead of
'switch' has precedence (shell) but the 'of' is totally new. Not that that's
necessarily a problem, but to me, the switch+case naming is a lot easier to
remember. However, I am a C programmer, so I'm bound to remember it well :)

> Possible refinements:

> * Multiple values in a case

>   CONSTANT, CONSTANT, ..., CONSTANT:

Meaning what ? Any one of them ? That would solve one part of the
fallthrough problem, but would require tuple-constants to be parenthesised.
It's probably the most pythonic solution, though.

The part of the fallthrough problem it solves is where you want multiple
values to trigger the same suite. In C that is:

   switch(spam) {
   case SPAM:
   case HAM:
   case EGGS:
       ....

but that works due to fallthrough. Doing it like that for Python (and
requiring 'case SPAM: pass' for the 'case' that requires an empty body)
doesn't strike me as terribly elegant or Pythonic. So yes, I think
'alternatives' (so to speak) should be expressed like that, much like it is
in the 'except' case. (no pun intended.)


> * Ranges in a case

>   CONSTANT..CONSTANT:

Would require range-literals. PEP 204 :-) Also keep in mind 'CONSTANT' can
be any hashable constant (regular or unicode strings, ints, longs, floats,
tuples.) How do you do a range of floats ?

> although that would require something other than a dict,
> maybe a binary search.

Implementation detail. :)

> Also could lead to arguments about
> whether the endpoint should be inclusive or exclusive!

The range-literal PEP should solve that.

> Maybe it should be spelt

>   range(CONSTANT, CONSTANT):

Hrm, possible.... but a tad obscure, not to mention hackish in the
implementation. 'range(1, 10)' is almost an expression, but we can't allow
expressions (even 'constant-expressions' such as C defines them) because we
don't do any constant folding in Python. I'd say not to go there now. It can
always be added later (just like constant-expressions.)

The range issue could possibly be solved using a programming trick (I mean
technique) such as:

ranges = [0 for x in range(10)] + [1 for x in range(10,20)] + [... etc]

switch ranges[num]:
case 0: num_in_range(10)
case 1: num_in_range(10,20)
case 2: ... etc.

For more advanced range-switching, you'd make a class to help in the
range-to-index translation.

-- 
Thomas Wouters <thomas@xs4all.net>

Hi! I'm a .signature virus! copy me into your .signature file to help me spread!