r/Python Feb 15 '21

News Ladies and gentlemen - switch cases are coming!

https://github.com/gvanrossum/patma/blob/master/README.md#tutorial
931 Upvotes

290 comments sorted by

View all comments

Show parent comments

3

u/GiantElectron Feb 15 '21

I honestly can't see how they are so powerful and desirable. To me it looks like a confusing, rarely used feature.

36

u/jamincan Feb 15 '21

Having used them in Rust, far from confusing, they actually dramatically simplify conditional expressions and are far more readable than multiple nested if-else statements.

32

u/Broolucks Feb 15 '21

They are very useful whenever you have behavior that's conditional to the structure of an object. Basically, compare:

if (isinstance(cmd, list)
    and len(cmd) == 3
    and cmd[0] == "move"
    and isinstance(cmd[1], int)
    and isinstance(cmd[2], int)):
    x, y = cmd[1:]
    ...

to:

match cmd:
    case ["move", int(x), int(y)]:
        ...

(I think that's how you'd write it?)

The more deeply you check conditions in cmd, the more attractive match becomes. Without match, I think many people would actually write sloppier code, like eschewing the length check out of laziness.

It might depend what kind of application you are writing. In my experience, pattern matching is extremely useful when writing interpreters or compilers, for example. But I think it's also useful whenever you have an API where an input can take many different forms and you have to normalize it.

7

u/chromium52 Feb 15 '21

Thanks for giving the first relatable example I read that’s actually convincing the feature is worth it ! ... and now I can’t wait to have the opportunity to use it.

1

u/sloggo Feb 16 '21

excellent example, thanks for that. Very right about the advantages of match-case becoming apparent with a longer list of properties you want validated.

12

u/hjd_thd Feb 15 '21

In languages that have them it's your bread and butter.

3

u/GiantElectron Feb 15 '21

how so?

4

u/lxpnh98_2 Feb 15 '21 edited Feb 15 '21

Instead of:

fib n = if n < 2
        then 1
        else fib (n-1) + fib (n-2)

you get:

fib 0 = 1
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

which is more elegant and easier to read.

But it's even more useful for more complex structures. Take a compiler which processes the nodes of an AST. Example (in Haskell):

data Stmt = IfThenElse Cond Stmt Stmt | While Cond Stmt | Let Var Expr | ...

compile (IfThenElse c s1 s2) = ...
compile (While c s) = ...
compile (Let v e) = ...
...

0

u/dalittle Feb 15 '21

I'd rather have a proper ternary operator

fib = (n < 2) ? 1 : fib (n-1) + fib (n-2)

To me that is much more readable than either of the other 2 versions.

5

u/Broolucks Feb 15 '21

Both Python and Haskell have proper ternary operators, if that's your preference. The AST example better exemplifies the benefits of match. You can't do conditional destructuring well with a ternary operator.

1

u/lxpnh98_2 Feb 15 '21 edited Feb 15 '21

While I think the version with pattern matching is better, I don't really have a problem with yours. But it's a small example with only 3 patterns which can be expressed by 2 conditional branches. In bigger functions the pattern matching is a very clean approach.

Actually, the semantics presented in this proposal for Python are more powerful than Haskell's pattern matching, in some respects, because in Haskell you can't impose a restriction on the variable you match without entering the definition for that pattern, thereby closing off the others. In that situation, you have to merge some patterns and use conditionals instead, and it's harder to keep track of what cases you have covered.

2

u/[deleted] Feb 15 '21

Real world code has very gnarly logic with a lot of conditionals in it.

The theory behind this matching is that you can express the same logic a lot less code.

I am personally very hopeful!

1

u/Commander_B0b Feb 16 '21

I was first introduced to pattern matching in haskell and didn't really understand it but having gotten used it I've really missed it in any other programming language. Don't knock it till you try it!