I’ve made a final round of updates to PEP 642 and submitted it to the
Steering Council for consideration alongside PEP 634.
As usual, the rendered version can be found here:
https://www.python.org/dev/peps/pep-0642/
There's a Discourse thread at
https://discuss.python.org/t/pep-642-v3-explicit-pattern-syntax-for-structural-pattern-matching/6459,
and the rest of the email covers the same points as the opening post
in that thread.
There are some pretty significant changes relative to v2, although I
did already discuss most of them in the v2 thread at
https://discuss.python.org/t/pep-642-constraint-pattern-syntax-for-structural-pattern-matching/5614
The PEP itself contains a list of major changes relative to PEP 634,
so I won’t repeat that here:
https://www.python.org/dev/peps/pep-0642/#appendix-c-summary-of-changes-relative-to-pep-634
Instead I’ll summarise the parts that I consider most important:
* ensuring that all “binding to the right” operations use the as
keyword. This drove changes to both mapping patterns and class
patterns.
* explicitly qualifying both name bindings and value constraints with
`as`, `==`, or `is`. This change makes it possible to make pattern
matching available to users without having to resolve the thorny
questions of what bare names and attribute references should do by
default. It also opens up the possibility of potentially adding more
value constraint options later (like `in` , `is not`, and `!=`) if
those operations seem sufficiently compelling to be worth adding.
* explicitly decoupling sequence pattern matching from iterable
unpacking. The change to require qualification of name binding
operations already breaks the alignment between the two, and that
created an opportunity to simplify the grammar by only allowing square
bracket based sequence patterns and eliminating both open sequence
patterns and parenthesis based sequence patterns
* changing class patterns to draw more of their syntactic inspiration
from mapping patterns rather than from class instantiation
* explicitly representing patterns in the AST, rather than treating
patterns as pseudo-expressions all the way through to the code
generation layer. Skipping this step makes the code fragile and hard
to follow, as there isn’t actually any point in the AST that accepts
both expressions and patterns, but with pattern parsing reusing
expression nodes, you can’t tell from just looking at the AST which
nodes expect subexpressions and which expect subpatterns.
I’ll also quote the example match statement from the PEP abstract,
which extracts “host” and “port” details from a 2 item sequence, a
mapping with “host” and “port” keys, any object with “host” and “port”
attributes, or a “host:port” string, treating the “port” as optional
in the latter three cases:
port = DEFAULT_PORT
match expr:
case [as host, as port]:
pass
case {"host" as host, "port" as port}:
pass
case {"host" as host}:
pass
case object{.host as host, .port as port}:
pass
case object{.host as host}:
pass
case str{} as addr:
host, __, optional_port = addr.partition(":")
if optional_port:
port = optional_port
case __ as m:
raise TypeError(f"Unknown address format: {m!r:.200}")
port = int(port)
Cheers,
Nick.
--
Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@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/GQHKW5KHXWZ3Y2E2KOJ72GT3IRGGEEUE/
Code of Conduct: http://python.org/psf/codeofconduct/
Steering Council for consideration alongside PEP 634.
As usual, the rendered version can be found here:
https://www.python.org/dev/peps/pep-0642/
There's a Discourse thread at
https://discuss.python.org/t/pep-642-v3-explicit-pattern-syntax-for-structural-pattern-matching/6459,
and the rest of the email covers the same points as the opening post
in that thread.
There are some pretty significant changes relative to v2, although I
did already discuss most of them in the v2 thread at
https://discuss.python.org/t/pep-642-constraint-pattern-syntax-for-structural-pattern-matching/5614
The PEP itself contains a list of major changes relative to PEP 634,
so I won’t repeat that here:
https://www.python.org/dev/peps/pep-0642/#appendix-c-summary-of-changes-relative-to-pep-634
Instead I’ll summarise the parts that I consider most important:
* ensuring that all “binding to the right” operations use the as
keyword. This drove changes to both mapping patterns and class
patterns.
* explicitly qualifying both name bindings and value constraints with
`as`, `==`, or `is`. This change makes it possible to make pattern
matching available to users without having to resolve the thorny
questions of what bare names and attribute references should do by
default. It also opens up the possibility of potentially adding more
value constraint options later (like `in` , `is not`, and `!=`) if
those operations seem sufficiently compelling to be worth adding.
* explicitly decoupling sequence pattern matching from iterable
unpacking. The change to require qualification of name binding
operations already breaks the alignment between the two, and that
created an opportunity to simplify the grammar by only allowing square
bracket based sequence patterns and eliminating both open sequence
patterns and parenthesis based sequence patterns
* changing class patterns to draw more of their syntactic inspiration
from mapping patterns rather than from class instantiation
* explicitly representing patterns in the AST, rather than treating
patterns as pseudo-expressions all the way through to the code
generation layer. Skipping this step makes the code fragile and hard
to follow, as there isn’t actually any point in the AST that accepts
both expressions and patterns, but with pattern parsing reusing
expression nodes, you can’t tell from just looking at the AST which
nodes expect subexpressions and which expect subpatterns.
I’ll also quote the example match statement from the PEP abstract,
which extracts “host” and “port” details from a 2 item sequence, a
mapping with “host” and “port” keys, any object with “host” and “port”
attributes, or a “host:port” string, treating the “port” as optional
in the latter three cases:
port = DEFAULT_PORT
match expr:
case [as host, as port]:
pass
case {"host" as host, "port" as port}:
pass
case {"host" as host}:
pass
case object{.host as host, .port as port}:
pass
case object{.host as host}:
pass
case str{} as addr:
host, __, optional_port = addr.partition(":")
if optional_port:
port = optional_port
case __ as m:
raise TypeError(f"Unknown address format: {m!r:.200}")
port = int(port)
Cheers,
Nick.
--
Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@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/GQHKW5KHXWZ3Y2E2KOJ72GT3IRGGEEUE/
Code of Conduct: http://python.org/psf/codeofconduct/