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 Mon, 16 Nov 2020 at 14:44, Mark Shannon <m...@hotpy.org> 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 -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at
> https://mail.python.org/archives/list/python-dev@python.org/message/BTPODVYLPKY5IHWFKYQJICONTNTRNDB2/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/J55MO5VWDYAAAXEE266BVXGLZJLFW2O2/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to