Every so often, someone suggests that Python should have a pattern matching 
case statement like Scala, C#, Swift, Haskell, etc. Or they just suggest that 
“Python needs algebraic data types” but end up concluding that the biggest part 
Python is missing is not the types themselves, but a practical way to do 
something useful with them, which basically means pattern matching.

Anyway, with the addition of the walrus operator and @dataclass, Python is 
actually a lot closer than it used to be. I believe with just two smallish 
syntax features, it would be possible to do almost anything you’d ever want in 
a library.

The first is to extend unpacking assignment to target-or-expression lists. Like 
this:

    x, 0, z = vec

Just like `x, y, z = vec`, this raises a TypeError if vec isn’t Iterable, and a 
ValueError if it has more or fewer than 3 elements, and otherwise, it binds x 
and z to the first and third elements. But it doesn’t bind anything to the 
second element; instead, it checks if that element is 0, and, if not, raises a 
ValueError.

The second is an “if try” statement, which tries an expression and runs the 
body if that doesn’t raise (instead of if it’s truthy), but jumps to the next 
elif/else/statement (swallowing the exception) if it does. The actual value of 
the expression is discarded, but the walrus operator takes care of that:

    if try 0, y, z := vec:
        # do yz plane stuff
    elif try x, 0, z := vec:
        # do xz plane stuff
    elif try x, y, 0 := vec:
        # do xy plane stuff
    elif x, y, z := vec:
        # do slow/imprecise/whatever 3D stuff
    else:
        raise TypeError(f'{vec} is not a 3-vector!')

Alternatively, this could just be a try expression that can be used anywhere: 
it’s truthy if evaluating doesn’t raise, falsey if it does. But I don’t think 
it’s needed anywhere but if/elif.

Anyway, neither of these features seems very useful on its own. (It should be 
obvious how to rewrite that example as something just as readable that just 
unpacks and then checks the values with normal if.)

But I think the two of them together will allow a pure-library implementation 
of pattern matching syntax that reads nicely and can do everything most other 
languages do—in particular, concisely and readably pattern match and 
deconstruct dataclasses (and other types with an opt-in protocol or registry, 
but dataclasses would work out of the box the way Scala case classes, Swift 
structs, etc. do).

If people think either of these features is too horrible to contemplate no 
matter what the potential benefits, I won’t bother working through the details.

But if people do want to see the details (including some good motivating 
examples—I’ll go through tutorials for those other languages to find some that 
don’t involve recursing into cons lists and other stuff you wouldn’t want to do 
in Python…), I’ll be happy to do so, and, if it works out, turn this into a 
more detailed proposal.

And obviously, if people want to bikeshed the spelling before even seeing what 
it’s good for, well, this is Python-ideas. :)
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/W64QFNZVAGU2EMHTLDXHRGJ7V7TYBR5R/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to