[Python-Dev] Re: The semantics of pattern matching for Python

2020年11月20日 02:55:52 -0800

Hello again Mark, I took some time looking in more detail at your proposal,
and these are my thoughts. I'm writing with the assumption that this
proposal describes some "internal" representation of match statements which
is never exposed to the users (so I'd mostly steer away from
lexical/syntactic preferences).
My first general thought is that this is a useful way to describe and
discuss implementation, although I wouldn't wait on refinement of this to
choose whether to accept/reject PEP 634 (or 642, or your favourite
alternative), work can be done on parallel. It may be a good idea to wait
for your proposal to be refined before landing a specific implementation
into CPython (including how the chosen implementation, assuming it's
accepted, desugars into your semantics).
Going into more details, here's a list of thoughts on more specific points:
 1. You mention a goal about "erroneous patterns" (which I'm still not
 sure I agree on), and your proposal addresses that by forcing classes to be
 explicit (via __atributes__ and __deconstruct__) about what attributes are
 accepted as matches. This is against one design principle that's not in
 your list but it was (at least implicitly) in PEP622 and 634: "pattern
 matching must allow matching objects on types not specifically designed for
 it"; this will allow to apply this feature to classes that you can not
 modify (like instances created by a 3rd party library ). That's why PEP634
 relies on getattr() ; that could be extended in the feature (providing some
 override using attributes like yours) but that wouldn't be required by
 default
 2. We considered and discussed something similar to the __deconstruct__
 approach (as an override for getattr()), and also noted is potentially
 expensive, requiring to allocate an object and evaluate *all* attributes,
 even if only one is required. That is against the principle of " it should
 perform at least as well as an equivalent sequence of if, elif statements."
 3. You removed or patterns, and added multiple "case P" for each case
 body. This easily covers cases where the multiple options are at top level
 in the pattern, but if the or-pattern is in a subpattern you have to
 duplicate much of the outer context. And this "duplication" is actually
 exponential on the number of or patterns, so for matching the pattern
 "[0|1, 0|1, 0|1, 'foo'|'bar'|'baz']" you need to desugar this into 24 case
 clauses.
 4. Something else about decomposing patterns into multiple case clauses
 is that it makes it harder to express the constraint that all alternatives
 must bind the same variable.
 5. I found a bit confusing to read the multiple cases on top. It looks
 like C switch statements, which fall-through by default, but in a context
 where some case clauses do fall-through (if empty) and others aren't (if
 they have a body, even if it's "pass"). I know this is not user exposed
 syntax so it's not that important, but this made the description harder to
 read for me.
 6. Given the previous points, added to not seeing the gains of not
 putting the or patterns into the desugared version, I'd prefer it to be
 included in the desugaring.
 7. I think there's some surprising behaviour in the assignments being
 done after a successful match but before the guard is evaluated. In your
 proposal the guard has no access to the variables, so it has to be compiled
 differently (using 0,ドル 1,ドル ... rather than the actual names that appear in
 the expression). And if this guard calls a function which exposes those
 variables in any way (for example if the variable is in a closure) I think
 the behaviour may be unexpected /surprising; same if I stop a debugger
 inside that function and try to inspect the frame where the matching
 statement is.
 8. I like your implementation approach to capture on the stack and then
 assign. I was curious if you considered, rather than using a variable
 number of stack cells using a single object/dict to store those values. The
 compiler and the generated bytecode could end up being simpler, and you
 need less stack juggling and possibly no PEEK operation. a small list/array
 would suffice, but a dict may provide further debugging opportunities (and
 it's likely that a split table dict could make the representation quite
 compact). I know this is less performant but I'm also thinking of
 simplicity.
 9. I think your optimisation approaches are great, the spec was made lax
 expecting for people like you to come up with a proposal of this kind :) I
 don't think the first implementation of this should be required to
 optimize/implement things in a certain way, but if the spec is turned into
 implementation dependent and then fixed, it shouldn't break anything (it's
 like the change in dictionary order moving to "undefined/arbitrary" to
 "preserving insertion order") and can be done later one
Thanks again,
Daniel
On 2020年11月16日 at 14:44, Mark Shannon <[email protected]> wrote:
> Hi everyone,
>
> There has been much discussion on the syntax of pattern matching for
> Python (in case you hadn't noticed ;)
>
> Unfortunately the semantics seem to have been somewhat overlooked.
> What pattern matching actually does seems at least as important as the
> syntax.
>
>
> I believe that a pattern matching implementation must have the following
> properties:
>
> * The semantics must be precisely defined.
> * It must be implemented efficiently.
> * Failed matches must not pollute the enclosing namespace.
> * Objects should be able determine which patterns they match.
> * It should be able to handle erroneous patterns, beyond just syntax
> errors.
>
> PEP 634 and PEP 642 don't have *any* of these properties.
>
>
> I've written up a document to specify a possible semantics of pattern
> matching for Python that has the above properties, and includes reasons
> why they are necessary.
>
>
> https://github.com/markshannon/pattern-matching/blob/master/precise_semantics.rst
>
> It's in the format of a PEP, but it isn't a complete PEP as it lacks
> surface syntax.
>
> Please, let me know what you think.
>
> Cheers,
> Mark.
> _______________________________________________
> Python-Dev mailing list -- [email protected]
> To unsubscribe send an email to [email protected]
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/[email protected]/message/BTPODVYLPKY5IHWFKYQJICONTNTRNDB2/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
Python-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/[email protected]/message/J55MO5VWDYAAAXEE266BVXGLZJLFW2O2/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to