I've never understood why Python's pattern-matching isn't more general.
First, "case foo.bar" is a value match, but "case foo" is a name capture. Python could have defined "case .foo" to mean "look up foo as a variable the normal way" with zero ambiguity, but chose not to.
Second, there's no need to special-case some builtin types as matching whole values. You can write "case float(m): print(m)" and print the float that matched, but you can't write "case MyObject(obj): print(obj)" and print your object. Python could allow "..." or "None" or something in __match_args__ to mean "the whole object", but didn't.
While the article is very entertaining, I'm not a fan of the pattern matching in Python.
I wish for some linter rule that can forbid the usage of pattern matching.
Could someone explain just what's so bad about this?
My best guess is that it adds complexity and makes code harder to read in a goto-style way where you can't reason locally about local things, but it feels like the author has a much more negative view ("crimes", "god no", "dark beating heart", the elmo gif).
The real crime is the design of Python's pattern matching in the first place:
match status:
case 404:
return "Not found"
not_found = 404
match status:
case not_found:
return "Not found"
Everywhere else in the language, you can give a constant a name without changing the code's behaviour. But in this case, the two snippets are very different: the first checks for equality (`status == 404`) and the second performs an assignment (`not_found = status`).
My favorite Python "crime" is that a class that defines __rrshift__, instantiated and used as a right-hand-side, lets you have a pipe operator, regardless of the left-hand-side (as long as it doesn't define __rshift__).
It's reasonably type-safe, and there's no need to "close" your chain - every outputted value as you write the chain can have a primitive type.
It shines in notebooks and live coding, where you might want to type stream-of-thought in the same order of operations that you want to take place. Need to log where something might be going wrong? Tee it like you're on a command line!
Idiomatic? Absolutely not. Something to push to production? Not unless you like being stabbed with pitchforks. Actually useful for prototyping? 1000%.
I don't think this is necessarily a "crime", I could see this being useful.
An example that uses a similar approach would be if you had a metaclass that overrode __instancecheck__ to return true if a string matched a regular expression. Then you could create (dynamically defined) classes that used that metaclass to use in match statements to march a string against multiple regexes. Unfortunately, I can't think of a good way to extract any capture groups.
ok, took me a bit to wrap my head around whats going on here, but actually this is neat, and probably useful.
Ive been hobbying in python for a decade plus at this point and it still ties my brain in knots sometimes with how it works at runtime. I do enjoy working with it though.
E: just to clarify if you're going to use this don't bury it deep in a multi file code structure, explicitly have it in the same file as you use it, otherwise people will get confused.
Personally, I have never liked the PEP 634 pattern matching. I write a lot of code in Python. 99% of the time when I could use pattern matching, I am going to use simple if statements or dictionaries. Most of the time, they are more straightforward and easier to read, especially for developers who are more familiar with traditional control flow.
I've been doing Python full time for about 4 years now.
I always found that when pattern matching is used it always ends up increasing the cognitive load significantly. It shines for simple cases, and for precise object pattern sniping. But anything that acts on nested objects or more than 3 members with multiple case statements is pre-programmed for failure. What makes it worse, is that there seems to be a trend where other Python adepts will default to pattern matching over everything else, like a too good of a hammer.
18 comments
[ 2.9 ms ] story [ 62.7 ms ] threadFirst, "case foo.bar" is a value match, but "case foo" is a name capture. Python could have defined "case .foo" to mean "look up foo as a variable the normal way" with zero ambiguity, but chose not to.
Second, there's no need to special-case some builtin types as matching whole values. You can write "case float(m): print(m)" and print the float that matched, but you can't write "case MyObject(obj): print(obj)" and print your object. Python could allow "..." or "None" or something in __match_args__ to mean "the whole object", but didn't.
My best guess is that it adds complexity and makes code harder to read in a goto-style way where you can't reason locally about local things, but it feels like the author has a much more negative view ("crimes", "god no", "dark beating heart", the elmo gif).
https://x.com/brandon_rhodes/status/1360226108399099909
It's reasonably type-safe, and there's no need to "close" your chain - every outputted value as you write the chain can have a primitive type.
It shines in notebooks and live coding, where you might want to type stream-of-thought in the same order of operations that you want to take place. Need to log where something might be going wrong? Tee it like you're on a command line!Idiomatic? Absolutely not. Something to push to production? Not unless you like being stabbed with pitchforks. Actually useful for prototyping? 1000%.
Looks a lot like function composition with the arguments flipped, which in Haskell is `>>>`. Neat!
But since you’re writing imperative code and binding the result to a variable, you could also compare to `>>=`.
(https://downloads.haskell.org/~ghc/7.6.2/docs/html/libraries...)
I wanted to wash my eyes the first time I saw it.
An example that uses a similar approach would be if you had a metaclass that overrode __instancecheck__ to return true if a string matched a regular expression. Then you could create (dynamically defined) classes that used that metaclass to use in match statements to march a string against multiple regexes. Unfortunately, I can't think of a good way to extract any capture groups.
Ive been hobbying in python for a decade plus at this point and it still ties my brain in knots sometimes with how it works at runtime. I do enjoy working with it though.
E: just to clarify if you're going to use this don't bury it deep in a multi file code structure, explicitly have it in the same file as you use it, otherwise people will get confused.
Crimes with Python's pattern matching
406 points on Aug 2, 2022. 120 comments
https://news.ycombinator.com/item?id=32314368