Yet Another Switch-Case Syntax Proposal

Ian Kelly ian.g.kelly at gmail.com
Wed Apr 2 14:12:09 EDT 2014


On Wed, Apr 2, 2014 at 8:53 AM, Lucas Malor <3kywjyds5d at snkmail.com> wrote:
> Hi all. I would proposeto you all a switch-case syntax for Python. I already read PEP 3103 and I'm not completely satisfied by any of the proposed solutions. This is my proposal:

A more suitable place to propose this would be the python-ideas mailing list.

> switch_stmt ::=  "switch" identifier "case" expression_list ":" suite
>     ("case" expression_list ":" suite)*
>     ["else" ":" suite]

Why just just an identifier after the switch keyword instead of an
expression?  There are many cases where a user might wish to do
something along the lines of "switch values[0] case 42:"

> Expression list should yield an iterable. The case suite will be executed if the variable of the identifier is a member of the iterable.

An expression_list is one or more independent expressions separated by
commas that don't create a tuple.  If you just want an iterable, then
it should just be one expression.  But I'm not sure I like that.
Additionally, what if the value that you want to match is itself a
tuple?  If I write "switch 1, 2, 3 case 1, 2, 3:" will it match
against the entire tuple or will it try to match against the
individual ints and fail?  I prefer the "case in" syntax of
Alternative B of PEP 3103 here; it reads naturally and makes explicit
in the syntax whether you're matching against an individual object or
a grouping of objects.

> For example, in a "switch x" statement, the code "case iterable: " is identical to "if x in iterable: " (or elif etc). So if you want to perform the same case block for more than one value, you have only to specify a tuple, a range etc.

__contains__ is not part of the interface for iterables; it is defined
for containers only.  So if the matching expression evaluates to a
container that could be the code equivalent, but for arbitrary
iterables the equivalent code would have to be:

    for item in iterable:
        if value == item:
            # suite
            break
    else:
        # move on to the next case

Which is unlikely to be any more efficient than a simple elif chain.

> Fallthrough is disabled by default. The continue keyword cause to skip all the remaining current case suite. The next case will be checked. You can't use the continue keyword in the else clause.

If we overload the continue keyword in this way, then a continue can't
be used within the switch to control a loop that the switch is nested
within.  Instead of disabling fallthrough by default, why not disable
it all together?  The container/iterable matching means that we can
already match multiple values to the same suite, so the only use
remaining for fallthrough would be the kind that creates code smell.

> Some random remarks:
> 1. switch is on the same line of the first case. This will avoid any unpythonic syntaxes like:

I like this better than any of the alternatives in the PEP.

> 4. I decided to not use already existing keyword like "if" or "in", since it will be misleading and problematic for syntax highlighters.

Syntax highlighters could easily distinguish between something like
"case in" and existing uses of "in".  The former starts with the
keyword "case", and the others do not.



More information about the Python-list mailing list