On 2020-06-26 16:54, Stéfane Fermigier wrote: [...]
Here's one example:
https://github.com/clojure/core.match%C2%A0(in particular: https://github.com/clojure/core.match/wiki/Understanding-the-algorithm%C2%A0).
Alson some insights from https://softwareengineering.stackexchange.com/questions/237023/pattern-match...
In this video <https://www.youtube.com/watch?v=dGVqrGmwOAw> I watched recently, Rich Hickey comments that he likes the destructuring part of languages like Scala, but not so much the pattern matching part, and he designed Clojure accordingly. That probably explains why the pattern matching is in a library and not as robust, although the kind of problems seen in the post you mentioned are clearly bugs. What Rich Hickey mentions as an alternative to pattern matching is multimethods <http://clojure.org/multimethods>. Most languages let you do polymorphic dispatch based on type. Some languages let you also do it based on a value. Using multimethods, Clojure lets you do it based on any arbitrary function. That's a pretty powerful concept. It comes down to the principle that programmers using a language should use the language's own best idioms. Trying to write Scala-like code in Clojure is going to have its difficulties, and vice versa.
It does look like the PEP tries to do two different things: "switch" instead of if/elif, and destructuring.
Would it be useful to introduce an operator for "isinstance", if it's so commonly used? Are the calls to it (in the relevant codebase) actually used in complex code that needs destructuring, or could we live with this (IS_A being a placeholder for bikeshedding, of course):
if shape IS_A Point: x, y = shape ... elif shape IS_A Rectangle: x, y, w, h = shape ... elif shape IS_A Line: x, y = line.start if line.start == line.end: print(f"Zero length line at {x}, {y}")
or:
queue: Union[Queue[int], Queue[str]] if queue IS_A IntQueue: # Type-checker detects unreachable code ...
There aren't many convincing examples for destructuring in the PEP, IMO.
The "mapping pattern" one could be rewritten as:
if route := config.get('route'): process_route(route) if subconfig := config.pop(constants.DEFAULT_PORT): process_config(sub_config, config)
Sequence destructuring examples ([_] for "short sequence") don't seem too useful. Would they actually improve lots of existing code?
Complex object /tree destructuring (like the is_tuple) is painful in Python, but then again, the new syntax also becomes quite inscrutable for complex cases. Is code like the is_tuple example in the Rationale actually common?
The "Sealed classes as algebraic data types" example looks like a good candidate for a dump() method or PEP 443 single dispatch, both of which should be amenable to static analysis.