David Mertz wrote:
On Mon, Nov 23, 2020 at 9:02 PM Brian Coleman firstname.lastname@example.org wrote:
Basically, I agree matching/destructuring is a powerful idea. But I also wonder how much genuinely better it is than a library that does not require a language change. For example, I could create a library to allow this: m = Matcher(arbitrary_expression) if m.case("StringNode(s)"): process_string(m.val.s) elif m.case("[a, 5, 6, b]"): process_two_free_vars(m.val.a, m.val.b) What you are proposing here is very similar in effect to executing pattern matching statements using eval. What is the advantage of implementing the pattern matching functionality in a library if the user interface for that functionality has the same pitfalls as eval? I don't understand the similarity with eval that you are
suggesting. My hypothetical library would store the value passed as initializer to Matcher, and provide a method .case(). That method would need to do some moderately complicated parsing of the pattern passed into it, but using parsing techniques, not any eval() call. Btw. I modified my above strawman just slightly to what might be a bit better API. If there are any free variables in the pattern, they would be provided by the Matcher object. For example, they could be attributes of the property m.val. Or I suppose we could make them attributes of the Matcher object itself, e.g. m.a and m.b, but I think name conflicts with e.g. m.case. Anyway, it's a strawman not an API design. If the pattern looked kinda like a class constructor (i.e. exactly the same as PEP 634 rules), the .case() method would do an isinstance() check before doing its other stuff. If the pattern looks like a list, it would scan the freevars inside it and match the constant values. And so on. The actual return value from .m.case(...) would be True or False (or at least something truthy or falsy). However, it MIGHT create some new attributes (or keys, or something else) on the Matcher object if the pattern actually matched. I agree the above is slightly less readable than PEP 635 syntax, but it seems to have the entire power of the proposal without changing Python syntax.
Because syntax errors in the patterns passed to the `case` method are detected at runtime, rather than at compile time, it is necessary to ensure that you have code coverage of every call to a `case` method to be confident that there are no syntax errors in the patterns.
By comparison, if the pattern matching syntax is built into the language, the compiler will detect syntax errors in any and all patterns in `case` clauses. I think that this is a major advantage as compared to implementing pattern matching via a library.