Yet Another Switch-Case Syntax Proposal

Chris Angelico rosuav at gmail.com
Wed Apr 2 17:50:47 EDT 2014


On Thu, Apr 3, 2014 at 1:53 AM, Lucas Malor <3kywjyds5d at snkmail.com> wrote:
> 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.
> I would suggest to add an exception for non-iterable variables, so that you don't have to write "case var, : " but simply "case var: " and it will be identical to "if x == var: ". It's a bit tricky but the alternative is ugly.
>

This is sounding like a nasty special case. I'm ambivalent on the
overall proposal (want to see some real-world usage examples and how
they read), but I don't like the "iterable vs non-iterable"
distinction. Compare:

case 1,2,3: # Tuple - checks for any of its members
case range(10,110,10): # Range object - beautiful, convenient!
case 42: # Non-iterable, works the way you'd expect
case {1:"Test",2:"Hello",3:[]}: # Dictionary, may be surprising
case "Test",: # Tuple with a single string in it - works but ugly
case "Test": # And there's your problem.

You now have three valid ways to interpret that last statement:
1) It matches the exact string "Test", the way people will expect
2) It matches any of the results of iterating over it
3) It matches anything where x in "Test" is true

The first option is a big fat special case, and one that'll get more
complicated as you start looking at subclasses and such. The second
means that "case x" is equivalent to "case tuple(x)", but I can't
imagine people would actually want that in real usage. The third is
the way you've described it so far, but again, I cannot imagine it as
anything other than highly surprising that my last statement above
will match "st" and "es".

It would be more invasive to the language, but possibly better, to
have a new magic method __case__ which gets called to see if this
object matches this switched object. If that isn't defined, an
equality check is done. Then all of the above cases can be made
unsurprising by simply defining __case__ on a tuple (membership test)
and a range (ditto, except that the members aren't specifically
instantiated); everything else will check equality. (Having a dict
check for its keys is surprising, IMO, and I don't mind that one not
working.) It'd make it a *lot* easier to ensure sane behaviour in
custom classes; if you want your class to function like a single unit,
don't define __case__, but if you want it to function like a
collection, set __case__=__in__. What do you reckon?

ChrisA



More information about the Python-list mailing list