Questions about about the DLS 2020
Hi Tobias, A couple of questions about the DLS 2020 paper. 1. Why do you use the term "validate" rather than "test" for the process of selecting a match? It seems to me, that this is a test, not a validation, as no exception is raised if a case doesn't match. 2. Is the error in the ast matching example, an intentional "simplification" or just an oversight? The example: ``` def simplify(node): match node: case BinOp(Num(left), '+', Num(right)): return Num(left + right) case BinOp(left, '+' | '-', Num(0)): return simplify(left) case UnaryOp('-', UnaryOp('-', item)): return simplify(item) case _: return node ``` is wrong. The correct version is ``` def simplify(node): match node: case BinOp(Num(left), Add(), Num(right)): return Num(left + right) case BinOp(left, Add() | Sub(), Num(0)): return simplify(left) case UnaryOp(USub(), UnaryOp(USub(), item)): return simplify(item) case _: return node ``` Cheers, Mark.
Hi Mark, Thank you for your interest and the questions. 1. This really comes down to how you look at it, or how you define pattern matching. The issue here is that the concept of pattern matching has grown into a large and somewhat diverse flock of interpretations and implementations (as a side note: interestingly enough, some of the only universally agreed-upon standards are to use `_` as a wildcard and not to mark names that capture/bind values---which are quite exactly the points most fiercely debatted here). Anyway, the paper presents the pattern matching structure we are proposing as one of three major variants of pattern matching: (a) Matching arguments to parameters in a function call, (b) Matching elements to elements in iterable unpacking, (c) Matching tree-like data to general patterns in a conditional pattern matching structure. The last one is the subject of the PEP and the paper. Nonetheless, in the first two cases (a) and (b), we find that indeed the computer will validate that the data matched the pattern and raise an exception if this fails. This is where this way of looking at it comes from. 2. Yes, that is indeed a deliberate simplification. The idea is to abstract away from the details of how exactly Python implements abstract syntax trees (which I honestly believe are irrelevant for the sake of the entire narrative). Moreover, using strings here allows us to exemplify the literal patterns, rather only showcasing only the constructor/class pattern. Essentially, this is a question of making the most out of the little space available. Since you have addressed this email to me directly, I would like to take this opportunity and briefly stress that this paper really grew out of a team effort. While I might have been the one pushing for an academic publication, the DLS'20 paper represents the input and ideas of all the authors, as well as the long discussions we had. Of course, I am happy to answer any questions about the paper, but it would be wrong to see me as the one person behind it. Cheers, Tobias Quoting Mark Shannon <mark@hotpy.org>:
Hi Tobias,
A couple of questions about the DLS 2020 paper.
1. Why do you use the term "validate" rather than "test" for the process of selecting a match?
It seems to me, that this is a test, not a validation, as no exception is raised if a case doesn't match.
2. Is the error in the ast matching example, an intentional "simplification" or just an oversight?
The example:
``` def simplify(node): match node: case BinOp(Num(left), '+', Num(right)): return Num(left + right) case BinOp(left, '+' | '-', Num(0)): return simplify(left) case UnaryOp('-', UnaryOp('-', item)): return simplify(item) case _: return node
```
is wrong.
The correct version is
``` def simplify(node): match node: case BinOp(Num(left), Add(), Num(right)): return Num(left + right) case BinOp(left, Add() | Sub(), Num(0)): return simplify(left) case UnaryOp(USub(), UnaryOp(USub(), item)): return simplify(item) case _: return node ```
Cheers, Mark. _______________________________________________ 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/ETZGYRCF... of Conduct: http://python.org/psf/codeofconduct/
On 11/16/2020 11:57 AM, Tobias Kohn wrote:
1. This really comes down to how you look at it, or how you define pattern matching. The issue here is that the concept of pattern matching has grown into a large and somewhat diverse flock of interpretations and implementations (as a side note: interestingly enough, some of the only universally agreed-upon standards are to use `_` as a wildcard and not to mark names that capture/bind values---which are quite exactly the points most fiercely debatted here).
_ looks OK to me. I was not aware of the 'standard' for name usage. But I just noticed the following:
Anyway, the paper presents the pattern matching structure we are proposing as one of three major variants of pattern matching: (a) Matching arguments to parameters in a function call,
Binding names are in the function definition and parameter signature, which is the pattern. Except for default argument expressions, value names are in the call that provided the data to be matched.
(b) Matching elements to elements in iterable unpacking,
Binding names are in the target pattern on the left. Value names are in the data source expression on the right.
(c) Matching tree-like data to general patterns in a conditional pattern matching structure.
Oh dear. We need both binding and value names in patterns. In case BinOp(Num(left), '+', Num(right)): obviously callable names BinOp and Num are treated as value names, with their signatures providing subpatterns. The not-obviously-callable names left and right are treated as binding names. I think that Python matching should use the all-caps convention. I like reusing the existing 'as x' syntax. I see if-elif-else structures, with assignment expressions included, as existing but limited conditional pattern matching structures. Binding names are clearly marked with ':='. --- Separate item: The Program 1 fact def needs a guard "if n > 1 and int(n) == n" to not raise Recursion error for negative and fractional args. -- Terry Jan Reedy
On Mon, Nov 16, 2020 at 9:03 AM Tobias Kohn <kohnt@tobiaskohn.ch> wrote:
Hi Mark,
Thank you for your interest and the questions.
1. This really comes down to how you look at it, or how you define pattern matching. The issue here is that the concept of pattern matching has grown into a large and somewhat diverse flock of interpretations and implementations (as a side note: interestingly enough, some of the only universally agreed-upon standards are to use `_` as a wildcard and not to mark names that capture/bind values---which are quite exactly the points most fiercely debatted here).
How many of those languages added pattern matching *later* and not at the earliest stages of the language (if not from the beginning)? And for those that added it later, how many of those didn't already have a convention surrounding "_"? My suspicion is "not many" and "not many". 😉 -Brett
Hi Brett, Without having really looked at the history of all the languages we mention in the PEPs, I have a hunch that most of them had pattern matching from quite the beginning or an early stage on, indeed. That being said, I think the question itself does not really make much sense, though. Programming languages are rarely if ever just invented out of the blue these days, but evolve from other languages that have gone before them. So, sure C++ and Objective-C both had objects and classes from the very beginning on, but if we take into consideration that they strongly build on C, we could argue just as well that OOP was a later addition to C. It really depends on your point of view. But since we are talking about different languages here, there is one example I could bring up. In C#, the underscore is a perfectly legal variable name. And yet, it is also used as a 'discard' [1] in newer versions. Moreover, F#, which certainly uses the underscore as a wildcard, runs on the same platform as C# and thus has to deal with this, too. Somehow, Microsoft and its developers seem able to cope with it. If I may widen the topic here a bit and seize the opportunity to go beyond just answering your email: I must admit that I find this entire discussion about the wildcard pattern rather mind-boggling. We seem all to accept the reality that ``match`` and ``case`` are context-sensitive keywords (i.e. they are both keywords and legal names) and that you cannot write ``123.bit_length()`` because the dot has several different meanings. But when it comes to the underscore and the idea that *as a pattern* it might simply not store a value, it is considered an insurmountable obstacle to learning and understanding pattern matching? Particularly because, after all, the underscore is in Python only a wildcard *by convention*? I think pattern matching has a lot in common with 'recursion': if you see it for the first time, it can be very hard to wrap you head around it and understand what is going on or why anyone would want to do such a thing. But once you understood it, it can be an extremely elegant solution to many problems. So, I really can fully understand a lot of the reservations brought forward about this feature and various aspects of it. And there were enough good and valid points brought up by the community, which we then integrated into and respected in our overhauled design---but that the wildcard pattern causes so much grief really is entirely beyond me... So, yes, most languages had pattern matching quite from the outset on (or not at all). But then, again, Python is about the only language I know to have introduced 'type' annotations so late in life rather than from its very beginning. It came at the cost of using the colon for something different than compound statements or dictionaries. If we consider how much annotations have been expanded in more recent versions of Python and how many tools make good use of it, I would call that a pretty successful move, though---even though all other languages might have had type annotations from their very birth. Kind regards, Tobias P.S. Sorry, I guess this turned out to be not so much a reply to your comment alone, as much more a reply to many a message and discussion that has been posted here over time. [1] https://docs.microsoft.com/en-us/dotnet/csharp/discards Quoting Brett Cannon <brett@python.org>:
On Mon, Nov 16, 2020 at 9:03 AM Tobias Kohn <kohnt@tobiaskohn.ch> wrote:
_Hi Mark,
Thank you for your interest and the questions.
1. This really comes down to how you look at it, or how you define pattern matching. The issue here is that the concept of pattern matching has grown into a large and somewhat diverse flock of interpretations and implementations (as a side note: interestingly enough, some of the only universally agreed-upon standards are to use `_` as a wildcard and not to mark names that capture/bind values---which are quite exactly the points most fiercely debatted here)._
_How many of those languages added pattern matching /later/ and not at the earliest stages of the language (if not from the beginning)? And for those that added it later, how many of those didn't already have a convention surrounding "_"? My suspicion is "not many" and "not many". 😉_ _ _ _-Brett_
On Tue, Nov 17, 2020 at 1:16 PM Tobias Kohn <kohnt@tobiaskohn.ch> wrote:
Hi Brett,
Without having really looked at the history of all the languages we mention in the PEPs, I have a hunch that most of them had pattern matching from quite the beginning or an early stage on, indeed. That being said, I think the question itself does not really make much sense, though. Programming languages are rarely if ever just invented out of the blue these days, but evolve from other languages that have gone before them. So, sure C++ and Objective-C both had objects and classes from the very beginning on, but if we take into consideration that they strongly build on C, we could argue just as well that OOP was a later addition to C. It really depends on your point of view.
But since we are talking about different languages here, there is one example I could bring up. In C#, the underscore is a perfectly legal variable name. And yet, it is also used as a 'discard' [1] in newer versions. Moreover, F#, which certainly uses the underscore as a wildcard, runs on the same platform as C# and thus has to deal with this, too. Somehow, Microsoft and its developers seem able to cope with it.
If I may widen the topic here a bit and seize the opportunity to go beyond just answering your email: I must admit that I find this entire discussion about the wildcard pattern rather mind-boggling. We seem all to accept the reality that ``match`` and ``case`` are context-sensitive keywords (i.e. they are both keywords and legal names)
Yes, because that's new syntax that's unambiguously new even if you have been programming in Python for decades.
and that you cannot write ``123.bit_length()`` because the dot has several different meanings.
But you can write `123 .bit_length()`. 😊 That's a parser limitation more than human understanding.
But when it comes to the underscore and the idea that *as a pattern* it might simply not store a value, it is considered an insurmountable obstacle to learning and understanding pattern matching?
I don't think "insurmountable" is a fair assessment of the general sentiment. But consistency is in the Zen of Python for a reason: "Special cases aren't special enough to break the rules". Now obviously "practicality beats purity" as well, but the argument "other languages do it this way" doesn't hold well for a language that doesn't use curly braces for scoping delineation. 😉
Particularly because, after all, the underscore is in Python only a wildcard *by convention*?
Yep, but PEP 634 not only changes the convention, it special-cases "_" to be different in how it can be used anywhere else in Python. And that convention is wide enough that tools like linters rely on it, so it's gone far enough to almost be a standard. It's like trying to redefine some slang term that hasn't made it into the dictionary yet, but based purely on how it's used in a sentence; it doesn't break the "rules", but it doesn't necessarily help using it that way mentally either (especially for those of us who have been using the "slang" for a decade or more). And to be clear, I'm not arguing for or against redefining the meaning of "_" for pattern matching, just trying to help explain why people are speaking up about it.
I think pattern matching has a lot in common with 'recursion': if you see it for the first time, it can be very hard to wrap you head around it and understand what is going on or why anyone would want to do such a thing. But once you understood it, it can be an extremely elegant solution to many problems. So, I really can fully understand a lot of the reservations brought forward about this feature and various aspects of it. And there were enough good and valid points brought up by the community, which we then integrated into and respected in our overhauled design---but that the wildcard pattern causes so much grief really is entirely beyond me...
Welcome to worrying about every little detail in language design. 😉 -Brett
So, yes, most languages had pattern matching quite from the outset on (or not at all). But then, again, Python is about the only language I know to have introduced 'type' annotations so late in life rather than from its very beginning. It came at the cost of using the colon for something different than compound statements or dictionaries. If we consider how much annotations have been expanded in more recent versions of Python and how many tools make good use of it, I would call that a pretty successful move, though---even though all other languages might have had type annotations from their very birth.
My question about adding pattern matching later was more to comment on the fact that the languages that use "_" for a wildcard pattern did it from early on, not later on; it had nothing to do with the proposal proposing pattern matching late in Python's history.
Kind regards, Tobias
P.S. Sorry, I guess this turned out to be not so much a reply to your comment alone, as much more a reply to many a message and discussion that has been posted here over time.
[1] https://docs.microsoft.com/en-us/dotnet/csharp/discards
Quoting Brett Cannon <brett@python.org>:
On Mon, Nov 16, 2020 at 9:03 AM Tobias Kohn <kohnt@tobiaskohn.ch> wrote:
*Hi Mark, Thank you for your interest and the questions. 1. This really comes down to how you look at it, or how you define pattern matching. The issue here is that the concept of pattern matching has grown into a large and somewhat diverse flock of interpretations and implementations (as a side note: interestingly enough, some of the only universally agreed-upon standards are to use `_` as a wildcard and not to mark names that capture/bind values---which are quite exactly the points most fiercely debatted here).*
*How many of those languages added pattern matching later and not at the earliest stages of the language (if not from the beginning)? And for those that added it later, how many of those didn't already have a convention surrounding "_"? My suspicion is "not many" and "not many". 😉*
*-Brett*
_______________________________________________ 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/KP2TVEAP... Code of Conduct: http://python.org/psf/codeofconduct/
On Wed, Nov 18, 2020 at 11:39 AM Brett Cannon <brett@python.org> wrote:
My question about adding pattern matching later was more to comment on the fact that the languages that use "_" for a wildcard pattern did it from early on, not later on; it had nothing to do with the proposal proposing pattern matching late in Python's history.
I suspect that historically there is a connection here; we used "_" in Python for a number of special purposes because it's defined to be an identifier by the lexer but not likely to be used as a "regular" identifier, being kind of an edge case. Like Python, many other languages inherited this from C, with its definition of identifiers as "letter (letter|digit)*" where "_" is considered a letter. Also, in Scala its usage in patterns is similarly different from the rest of the language; there, too, it is a normal variable name except in patterns. PS. Why do you think that this is "late in Python's history?" In 100 years people will chuckle about that. :-) -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
Hi Brett, Thanks for your replies. _> But you can write `123 .bit_length()`. 😊 That's a parser limitation more than human understanding._ Touché. I took this ambiguity of the dot so much for granted that I would not have thought of trying that. _> Yep, but PEP 634 not only changes the convention, it special-cases "_" to be different in how it can be used anywhere else in Python. [...]_ I feel this is a bit of a misunderstanding, though: the underscore is really only special as a pattern. Nothing in the PEP is changing anything outside of pattern matching. I think it is quite important that such a complex feature is kind of separate from the rest of the language. _> Welcome to worrying about every little detail in language design. 😉_ Cheers ^_^. To be fair, I learned a lot in this regard during the past months and I feel extremely lucky to have benefitted so much from working with these very smart and highly experienced team mates. At the same token, we researched and approached the topic from so many different angles that I feel quite comfortable with the result and think this turned out to be a solid proposal. _> [...] Now obviously "practicality beats purity" as well, but the argument "other languages do it this way" doesn't hold well for a language that doesn't use curly braces for scoping delineation. 😉_ I completely get that I fully agree with the intent of it. We obviously have to concentrate much more on OCaml, Pascal, and Basic, which do not use curly braces for scoping delineation, either ;-) ;-P. Honestly, though, I guess there is a certain grey area here. I am thinking, for instance, of things like a for-loop, which indicates iteration in about every language known(*), although there is research indicating that the keyword ``for`` itself is a rather bad choice. At some point, it just becomes so much a standard that it transcendents into some kind of "meta-language". I would argue that in this case, the burden of proof kind of reverses: you then need a very good argument why /_not_/ to stick to a universal standard. And somehow, "Python only sticks superficially and by convention to the standard but we want to be able to break the rules even in this case whenever we fancy" strikes me as particularly convincing... :) _> My question about adding pattern matching later was more to comment on the fact that the languages that use "_" for a wildcard pattern did it from early on, not later on; it had nothing to do with the proposal proposing pattern matching late in Python's history._ Hmm, yes I understand. Still, it is probably hard to make a solid argument either way, because only few languages really added pattern matching later, with most of them being statically typed, functional, and so on. So, there is not really much to go for I guess. It is probably Python's burden now to embark on adventures to seek out new worlds, new possibilities and boldly go where no snake has gone before... :) Kind regards, Tobias (*) And yes, I am fully aware of assembly, purely functional languages, brainf*, etc. Quoting Brett Cannon <brett@python.org>:
On Tue, Nov 17, 2020 at 1:16 PM Tobias Kohn <kohnt@tobiaskohn.ch> wrote:
_Hi Brett,
Without having really looked at the history of all the languages we mention in the PEPs, I have a hunch that most of them had pattern matching from quite the beginning or an early stage on, indeed. That being said, I think the question itself does not really make much sense, though. Programming languages are rarely if ever just invented out of the blue these days, but evolve from other languages that have gone before them. So, sure C++ and Objective-C both had objects and classes from the very beginning on, but if we take into consideration that they strongly build on C, we could argue just as well that OOP was a later addition to C. It really depends on your point of view.
But since we are talking about different languages here, there is one example I could bring up. In C#, the underscore is a perfectly legal variable name. And yet, it is also used as a 'discard' [1] in newer versions. Moreover, F#, which certainly uses the underscore as a wildcard, runs on the same platform as C# and thus has to deal with this, too. Somehow, Microsoft and its developers seem able to cope with it.
If I may widen the topic here a bit and seize the opportunity to go beyond just answering your email: I must admit that I find this entire discussion about the wildcard pattern rather mind-boggling. We seem all to accept the reality that ``match`` and ``case`` are context-sensitive keywords (i.e. they are both keywords and legal names)_
_Yes, because that's new syntax that's unambiguously new even if you have been programming in Python for decades._ _ _
_and that you cannot write ``123.bit_length()`` because the dot has several different meanings._
_But you can write `123 .bit_length()`. 😊 That's a parser limitation more than human understanding._ _ _
_ But when it comes to the underscore and the idea that *as a pattern* it might simply not store a value, it is considered an insurmountable obstacle to learning and understanding pattern matching?_
_I don't think "insurmountable" is a fair assessment of the general sentiment. But consistency is in the Zen of Python for a reason: "Special cases aren't special enough to break the rules". Now obviously "practicality beats purity" as well, but the argument "other languages do it this way" doesn't hold well for a language that doesn't use curly braces for scoping delineation. 😉_ _ _
_ Particularly because, after all, the underscore is in Python only a wildcard *by convention*?_
_Yep, but PEP 634 not only changes the convention, it special-cases "_" to be different in how it can be used anywhere else in Python. And that convention is wide enough that tools like linters rely on it, so it's gone far enough to almost be a standard. It's like trying to redefine some slang term that hasn't made it into the dictionary yet, but based purely on how it's used in a sentence; it doesn't break the "rules", but it doesn't necessarily help using it that way mentally either (especially for those of us who have been using the "slang" for a decade or more)._ _And to be clear, I'm not arguing for or against redefining the meaning of "_" for pattern matching, just trying to help explain why people are speaking up about it._
_ _
_I think pattern matching has a lot in common with 'recursion': if you see it for the first time, it can be very hard to wrap you head around it and understand what is going on or why anyone would want to do such a thing. But once you understood it, it can be an extremely elegant solution to many problems. So, I really can fully understand a lot of the reservations brought forward about this feature and various aspects of it. And there were enough good and valid points brought up by the community, which we then integrated into and respected in our overhauled design---but that the wildcard pattern causes so much grief really is entirely beyond me..._
_Welcome to worrying about every little detail in language design. 😉_ _-Brett_ _ _
_So, yes, most languages had pattern matching quite from the outset on (or not at all). But then, again, Python is about the only language I know to have introduced 'type' annotations so late in life rather than from its very beginning. It came at the cost of using the colon for something different than compound statements or dictionaries. If we consider how much annotations have been expanded in more recent versions of Python and how many tools make good use of it, I would call that a pretty successful move, though---even though all other languages might have had type annotations from their very birth._
_My question about adding pattern matching later was more to comment on the fact that the languages that use "_" for a wildcard pattern did it from early on, not later on; it had nothing to do with the proposal proposing pattern matching late in Python's history._ _ _
_Kind regards, Tobias
P.S. Sorry, I guess this turned out to be not so much a reply to your comment alone, as much more a reply to many a message and discussion that has been posted here over time.
[1] https://docs.microsoft.com/en-us/dotnet/csharp/discards
Quoting Brett Cannon <brett@python.org>:_
_ _
_On Mon, Nov 16, 2020 at 9:03 AM Tobias Kohn <kohnt@tobiaskohn.ch> wrote:_
__Hi Mark,
Thank you for your interest and the questions.
1. This really comes down to how you look at it, or how you define pattern matching. The issue here is that the concept of pattern matching has grown into a large and somewhat diverse flock of interpretations and implementations (as a side note: interestingly enough, some of the only universally agreed-upon standards are to use `_` as a wildcard and not to mark names that capture/bind values---which are quite exactly the points most fiercely debatted here).__
__How many of those languages added pattern matching /later/ and not at the earliest stages of the language (if not from the beginning)? And for those that added it later, how many of those didn't already have a convention surrounding "_"? My suspicion is "not many" and "not many". 😉__ __ __ __-Brett__
________________________________________________ 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/KP2TVEAP... Code of Conduct: http://python.org/psf/codeofconduct/_
On Wed, Nov 18, 2020 at 11:39 AM Brett Cannon <brett@python.org> wrote:
Now obviously "practicality beats purity" as well, but the argument "other languages do it this way" doesn't hold well for a language that doesn't use curly braces for scoping delineation. 😉
I see your smiley, and I believe I've addressed this point before, but I feel I have to point out once again that Python's design *does* actually try to follow other languages in many (most) ways, lest people think there is something wrong with following other languages' example, or that they get bonus points for being different. This is not a case of "feature envy" (often seen when people propose a feature that they like in another language without understanding Python). Pattern matching fills a real need and the design is about as Pythonic as it gets. -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
Not being able to use a particular variable name (such as match or case) in the limited context of matching is only a minor wart. Unfortunately, _ for internationalization is already a well-established convention for something that you might well want to do within each separate case. It isn't just that you can't call your variable match; it is that you can't do output without renaming what seems like a standard library function. Not insurmountable, but also not trivial.
But none of those limitations are there under our proposal. You can write this if you want: match = 1 match match: case case: print(case, match) And you can use _(“...”) anywhere in the case block and even in the guard. Just not as a pattern, but you can’t use f(1) there either... On Fri, Nov 20, 2020 at 09:44 Jim J. Jewett <jimjjewett@gmail.com> wrote:
Not being able to use a particular variable name (such as match or case) in the limited context of matching is only a minor wart. Unfortunately, _ for internationalization is already a well-established convention for something that you might well want to do within each separate case. It isn't just that you can't call your variable match; it is that you can't do output without renaming what seems like a standard library function.
Not insurmountable, but also not trivial. _______________________________________________ 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/PVETCKEW... Code of Conduct: http://python.org/psf/codeofconduct/
-- --Guido (mobile)
I suppose that does follow from treating _ specially by not binding to it at all; I just hadn't thought through it. (I think my mental model had it wiping out the previous binding even if the "new" one wasn't available.) So I would prefer that this be stated explicitly in the PEP. (And maybe it is by now; the last draft I read was a few versions ago.) -jJ
A notorious example here of the "not many" is this proposal (i.e. not part of the language yet) for C++: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1371r0.pdf . I think it's an interesting example given that this is a very mature language, not originally designed with pattern matching in mind, where _ is normally an identifier. Best, D. On Tue, 17 Nov 2020 at 19:30, Brett Cannon <brett@python.org> wrote:
On Mon, Nov 16, 2020 at 9:03 AM Tobias Kohn <kohnt@tobiaskohn.ch> wrote:
Hi Mark,
Thank you for your interest and the questions.
1. This really comes down to how you look at it, or how you define pattern matching. The issue here is that the concept of pattern matching has grown into a large and somewhat diverse flock of interpretations and implementations (as a side note: interestingly enough, some of the only universally agreed-upon standards are to use `_` as a wildcard and not to mark names that capture/bind values---which are quite exactly the points most fiercely debatted here).
How many of those languages added pattern matching *later* and not at the earliest stages of the language (if not from the beginning)? And for those that added it later, how many of those didn't already have a convention surrounding "_"? My suspicion is "not many" and "not many". 😉
-Brett _______________________________________________ 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/VZHF7GJ6... Code of Conduct: http://python.org/psf/codeofconduct/
I've had some things going on, and I'm still trying to catch up with the discussions here. Can someone tell me what would be the best place to look at the most recent proposal? Is one of the PEPs up to date? On Mon, Nov 16, 2020 at 7:02 PM Tobias Kohn <kohnt@tobiaskohn.ch> wrote:
Hi Mark,
Thank you for your interest and the questions.
1. This really comes down to how you look at it, or how you define pattern matching. The issue here is that the concept of pattern matching has grown into a large and somewhat diverse flock of interpretations and implementations (as a side note: interestingly enough, some of the only universally agreed-upon standards are to use `_` as a wildcard and not to mark names that capture/bind values---which are quite exactly the points most fiercely debatted here).
Anyway, the paper presents the pattern matching structure we are proposing as one of three major variants of pattern matching: (a) Matching arguments to parameters in a function call, (b) Matching elements to elements in iterable unpacking, (c) Matching tree-like data to general patterns in a conditional pattern matching structure.
The last one is the subject of the PEP and the paper. Nonetheless, in the first two cases (a) and (b), we find that indeed the computer will validate that the data matched the pattern and raise an exception if this fails. This is where this way of looking at it comes from.
2. Yes, that is indeed a deliberate simplification. The idea is to abstract away from the details of how exactly Python implements abstract syntax trees (which I honestly believe are irrelevant for the sake of the entire narrative). Moreover, using strings here allows us to exemplify the literal patterns, rather only showcasing only the constructor/class pattern.
Essentially, this is a question of making the most out of the little space available.
Since you have addressed this email to me directly, I would like to take this opportunity and briefly stress that this paper really grew out of a team effort. While I might have been the one pushing for an academic publication, the DLS'20 paper represents the input and ideas of all the authors, as well as the long discussions we had. Of course, I am happy to answer any questions about the paper, but it would be wrong to see me as the one person behind it.
Cheers, Tobias
Quoting Mark Shannon <mark@hotpy.org>:
Hi Tobias,
A couple of questions about the DLS 2020 paper.
1. Why do you use the term "validate" rather than "test" for the process of selecting a match?
It seems to me, that this is a test, not a validation, as no exception is raised if a case doesn't match.
2. Is the error in the ast matching example, an intentional "simplification" or just an oversight?
The example:
``` def simplify(node): match node: case BinOp(Num(left), '+', Num(right)): return Num(left + right) case BinOp(left, '+' | '-', Num(0)): return simplify(left) case UnaryOp('-', UnaryOp('-', item)): return simplify(item) case _: return node
```
is wrong.
The correct version is
``` def simplify(node): match node: case BinOp(Num(left), Add(), Num(right)): return Num(left + right) case BinOp(left, Add() | Sub(), Num(0)): return simplify(left) case UnaryOp(USub(), UnaryOp(USub(), item)): return simplify(item) case _: return node ```
Cheers, Mark. _______________________________________________ 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/ETZGYRCF... of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________ 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/CUNO57W7... Code of Conduct: http://python.org/psf/codeofconduct/
Hi Koos, Yes, our three PEPs (634/635/636) are up to date. PEP 634 is the technical specification, so you probably want to start with the tutorial (PEP 636) or the rationale (PEP 635). https://www.python.org/dev/peps/pep-0636/ https://www.python.org/dev/peps/pep-0635/ Perhaps the following link to a discussion and vote might be a good starting point to get an overview of the other proposals that are around: https://discuss.python.org/t/gauging-sentiment-on-pattern-matching/5770 Kind regards, Tobias Quoting Koos Zevenhoven <k7hoven@gmail.com>:
I've had some things going on, and I'm still trying to catch up with the discussions here. Can someone tell me what would be the best place to look at the most recent proposal? Is one of the PEPs up to date?
On Mon, Nov 16, 2020 at 7:02 PM Tobias Kohn <kohnt@tobiaskohn.ch> wrote:
_Hi Mark,
Thank you for your interest and the questions.
1. This really comes down to how you look at it, or how you define pattern matching. The issue here is that the concept of pattern matching has grown into a large and somewhat diverse flock of interpretations and implementations (as a side note: interestingly enough, some of the only universally agreed-upon standards are to use `_` as a wildcard and not to mark names that capture/bind values---which are quite exactly the points most fiercely debatted here).
Anyway, the paper presents the pattern matching structure we are proposing as one of three major variants of pattern matching: (a) Matching arguments to parameters in a function call, (b) Matching elements to elements in iterable unpacking, (c) Matching tree-like data to general patterns in a conditional pattern matching structure.
The last one is the subject of the PEP and the paper. Nonetheless, in the first two cases (a) and (b), we find that indeed the computer will validate that the data matched the pattern and raise an exception if this fails. This is where this way of looking at it comes from.
2. Yes, that is indeed a deliberate simplification. The idea is to abstract away from the details of how exactly Python implements abstract syntax trees (which I honestly believe are irrelevant for the sake of the entire narrative). Moreover, using strings here allows us to exemplify the literal patterns, rather only showcasing only the constructor/class pattern.
Essentially, this is a question of making the most out of the little space available.
Since you have addressed this email to me directly, I would like to take this opportunity and briefly stress that this paper really grew out of a team effort. While I might have been the one pushing for an academic publication, the DLS'20 paper represents the input and ideas of all the authors, as well as the long discussions we had. Of course, I am happy to answer any questions about the paper, but it would be wrong to see me as the one person behind it.
Cheers, Tobias
Quoting Mark Shannon <mark@hotpy.org>:_
_Hi Tobias,
A couple of questions about the DLS 2020 paper.
1. Why do you use the term "validate" rather than "test" for the process of selecting a match?
It seems to me, that this is a test, not a validation, as no exception is raised if a case doesn't match.
2. Is the error in the ast matching example, an intentional "simplification" or just an oversight?
The example:
``` def simplify(node): match node: case BinOp(Num(left), '+', Num(right)): return Num(left + right) case BinOp(left, '+' | '-', Num(0)): return simplify(left) case UnaryOp('-', UnaryOp('-', item)): return simplify(item) case _: return node
```
is wrong.
The correct version is
``` def simplify(node): match node: case BinOp(Num(left), Add(), Num(right)): return Num(left + right) case BinOp(left, Add() | Sub(), Num(0)): return simplify(left) case UnaryOp(USub(), UnaryOp(USub(), item)): return simplify(item) case _: return node ```
Cheers, Mark. _______________________________________________ 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/ETZGYRCF... of Conduct: http://python.org/psf/codeofconduct/_
________________________________________________ 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/CUNO57W7... Code of Conduct: http://python.org/psf/codeofconduct/_
On 11/16/2020 6:14 AM, Mark Shannon wrote:
2. Is the error in the ast matching example, an intentional "simplification" or just an oversight?
The example:
``` def simplify(node): match node: case BinOp(Num(left), '+', Num(right)): return Num(left + right) case BinOp(left, '+' | '-', Num(0)): return simplify(left) case UnaryOp('-', UnaryOp('-', item)): return simplify(item) case _: return node
```
is wrong.
This is not 'wrong' because the paper did not specify the signatures or definition of BinOp and UnaryOp or a specific module/package of origin. I took these as hypothetical classes in a hypothetical module that happens to use what I presume are ast class names.
The correct version is
``` def simplify(node): match node: case BinOp(Num(left), Add(), Num(right)): return Num(left + right) case BinOp(left, Add() | Sub(), Num(0)): return simplify(left) case UnaryOp(USub(), UnaryOp(USub(), item)): return simplify(item) case _: return node ```
Without knowing the signatures of the ast classes, having not worked with them as you have, passing instances of an Add class instead of an 'add' function looks wrong. How is one Add() different from another? For the didactic purpose of the example, this looks worse to me. For me, it is harder to read. -- Terry Jan Reedy
participants (8)
-
Brett Cannon
-
Daniel Moisset
-
Guido van Rossum
-
Jim J. Jewett
-
Koos Zevenhoven
-
Mark Shannon
-
Terry Reedy
-
Tobias Kohn