Yet Another Switch-Case Syntax Proposal
Steven D'Aprano
steve at pearwood.info
Wed Apr 2 21:06:06 EDT 2014
On Thu, 03 Apr 2014 08:50:47 +1100, Chris Angelico wrote:
> 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.
If we're going to add "switch" and "case" keywords, how about we also add
"of"? Then we can write:
switch x case of a, b, c:
# x equals one of a, b or c
case of d, e, f:
# x equals one of d, e or f
case in g, h, i:
# g, h and i must be iterable, and x is in one of them
else:
# none of the above match
That means we can cleanly match the common use-case where we want to
match something by equality, comparing against a list of 1 or more
(usually) scalar values:
case of 1, 2, [23, 42], 99:
assert x == 1 or x == 2 or x = [23,42] or x == 99
while also supporting the more complex case where we're matching against
one or more sequences:
case in (1, 2, 99), [23, 42]:
assert x == 1 or x == 2 or x = 99 or x == 23 or x == 42
Of course, in practice the second case is likely to be given dynamically,
not as literals:
case in LIST_OF_KEYWORDS:
...
Another option is to say that the cases being tested ought to be quite
small in number. If you're trying to do this:
case in range(100000000):
...
you're doing it wrong. That being the case, we only need to match by
equality:
case 1, 2, 3:
assert x == 1 or x == 2 or x == 3
and can write this when we want to match against a sequence or iterator:
case *LIST_OF_KEYWORDS:
...
and on the rare occasion we want to match against substrings, we can
build a wrapper class:
class Wrapper:
def __init__(self, value):
self.value = value
def __eq__(self, other):
return other in self.value
case Wrapper("Hello world!"):
# matches if x is a substring of "Hello world!"
But what's the advantage here? Since Python is not a static-typed
language, it's unlikely that there are any compile-time optimizations
that can be performed here. If there are any run-time optimizations that
a JIT optimizing compiler like Python can perform, it probably can
perform them just as well on a series of if...elif. So I'm not sure I see
what having special syntax for a switch-case statement gives us.
--
Steven
More information about the Python-list
mailing list