Pattern Matching -- Removing Name Binding from Partial Matching
I will explain it in the following few lines of code.. name = "George" year = 2021 d = {"name": "Mike", "year": 1919} match d: case {"name": name, "year": 1917}: print("match 1 found”) # I want to remove binding "name" here from partial matching case {"year": year, "name": "Michael”}: print("match 2 found”) # I want to remove binding "year" here from partial matching. # Basically removing all name bindings after every partial/failed matching case _: print("match not found!”) print(f"{name = }, {year = }”) ### Output ###: match not found! name = 'Mike', year = 1919 But I want :var: 'name' to stay being the global name “George" and :var: 'year' being the global year 2021 if an exact matching is not found. Maybe it is done the way it is for speed optimization (overhead reduction or something), but what if I don't care about speed and I care about having no un-intentional side-effects? Can we do something like the following to solve this issue? match d, partial_binding=False: case … : ... case … : ... with partial_binding=True by default. Any other idea in how to prevent name binding due to partial matching from happening? Any previous discussions on this? Thanks, Abdulla
The solution here is not to use the same name for two different concepts in the first place. Python doesn't have scopes associated with blocks, only with functions, and occasionally this means you have to pick your names carefully -- the same happens e.g. if you reuse a variable as a for-loop control variable. You can say that you don't want failed cases to bind any variables -- but what if the pattern succeeds and now a guard (the 'if' clause) needs to check the variable? We went down the route of how to make this work and in the end decided it would be too complicated. Or what if a case succeeds, and then after the match statement is over and done with (not in `case _:`) you still wanted access to the global 'name'? The long and short of it is that match statements are liable to any or all names bound in any of the patterns used, and your code is incorrect if you aren't prepared for that. A variant of the syntax to allow alternate semantics sounds worse. On Fri, Feb 12, 2021 at 10:30 PM Abdulla Al Kathiri < alkathiri.abdulla@gmail.com> wrote:
I will explain it in the following few lines of code..
name = "George" year = 2021
d = {"name": "Mike", "year": 1919}
match d:
case {"name": name, "year": 1917}: print("match 1 found”) # I want to remove binding "name" here from partial matching
case {"year": year, "name": "Michael”}: print("match 2 found”) # I want to remove binding "year" here from partial matching. # Basically removing all name bindings after every partial/failed matching
case _: print("match not found!”) print(f"{name = }, {year = }”)
### Output ###: match not found! name = 'Mike', year = 1919
But I want :var: 'name' to stay being the global name “George" and :var: 'year' being the global year 2021 if an exact matching is not found.
Maybe it is done the way it is for speed optimization (overhead reduction or something), but what if I don't care about speed and I care about having no un-intentional side-effects?
Can we do something like the following to solve this issue? match d, partial_binding=False: case … : ... case … : ... with partial_binding=True by default.
Any other idea in how to prevent name binding due to partial matching from happening? Any previous discussions on this?
Thanks,
Abdulla _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/HOFNVZ... Code of Conduct: http://python.org/psf/codeofconduct/
-- --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/>
My idea was that in the case of partial matching or full matching without passing the guard, the binding names has some sort of self destruction and return to the previous state. Using different variable names would resolve the issue and if I want to modify the global variables, I could choose to do so in the case block after the case succeeded. At least, this way, it would be more explicit, conveying the person intention (or forgetting if the original global value was later needed). I saw many people online talking about this the last couple of days so I thought I would bring it up here. Any other syntax variant could be used to achieve the same thing.
On 13 Feb 2021, at 9:51 PM, Guido van Rossum <guido@python.org> wrote:
The solution here is not to use the same name for two different concepts in the first place. Python doesn't have scopes associated with blocks, only with functions, and occasionally this means you have to pick your names carefully -- the same happens e.g. if you reuse a variable as a for-loop control variable.
You can say that you don't want failed cases to bind any variables -- but what if the pattern succeeds and now a guard (the 'if' clause) needs to check the variable? We went down the route of how to make this work and in the end decided it would be too complicated.
Or what if a case succeeds, and then after the match statement is over and done with (not in `case _:`) you still wanted access to the global 'name'? The long and short of it is that match statements are liable to any or all names bound in any of the patterns used, and your code is incorrect if you aren't prepared for that.
A variant of the syntax to allow alternate semantics sounds worse.
On Fri, Feb 12, 2021 at 10:30 PM Abdulla Al Kathiri <alkathiri.abdulla@gmail.com <mailto:alkathiri.abdulla@gmail.com>> wrote: I will explain it in the following few lines of code..
name = "George" year = 2021
d = {"name": "Mike", "year": 1919}
match d:
case {"name": name, "year": 1917}: print("match 1 found”) # I want to remove binding "name" here from partial matching
case {"year": year, "name": "Michael”}: print("match 2 found”) # I want to remove binding "year" here from partial matching. # Basically removing all name bindings after every partial/failed matching
case _: print("match not found!”) print(f"{name = }, {year = }”)
### Output ###: match not found! name = 'Mike', year = 1919
But I want :var: 'name' to stay being the global name “George" and :var: 'year' being the global year 2021 if an exact matching is not found.
Maybe it is done the way it is for speed optimization (overhead reduction or something), but what if I don't care about speed and I care about having no un-intentional side-effects?
Can we do something like the following to solve this issue? match d, partial_binding=False: case … : ... case … : ... with partial_binding=True by default.
Any other idea in how to prevent name binding due to partial matching from happening? Any previous discussions on this?
Thanks,
Abdulla _______________________________________________ Python-ideas mailing list -- python-ideas@python.org <mailto:python-ideas@python.org> To unsubscribe send an email to python-ideas-leave@python.org <mailto:python-ideas-leave@python.org> https://mail.python.org/mailman3/lists/python-ideas.python.org/ <https://mail.python.org/mailman3/lists/python-ideas.python.org/> Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/HOFNVZ... <https://mail.python.org/archives/list/python-ideas@python.org/message/HOFNVZ6KJA6SHCE4NCLPSK27XLDMK7VR/> Code of Conduct: http://python.org/psf/codeofconduct/ <http://python.org/psf/codeofconduct/>
-- --Guido van Rossum (python.org/~guido <http://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/>
On Sun, Feb 14, 2021 at 11:26 PM Abdulla Al Kathiri <alkathiri.abdulla@gmail.com> wrote:
My idea was that in the case of partial matching or full matching without passing the guard, the binding names has some sort of self destruction and return to the previous state. Using different variable names would resolve the issue and if I want to modify the global variables, I could choose to do so in the case block after the case succeeded. At least, this way, it would be more explicit, conveying the person intention (or forgetting if the original global value was later needed). I saw many people online talking about this the last couple of days so I thought I would bring it up here. Any other syntax variant could be used to achieve the same thing.
It's not about syntax. Python doesn't have an idea of "self destruction and return to the previous state". The nearest equivalent is a very special case at the end of an exception handler, where after "except Exception as e:" you'll get an implicit "e = None; del e" to prevent a refloop. That's not a return to the previous state, that's a conscious clearing of one reference. If this "unwinding" were desired, the best way would be to simply make it a permanent part of the match semantics - no syntax for selecting which behaviour you want. There's no backward compatibility to be maintained (yet). But that would be inconsistent with the rest of Python, where things happen step by step, and if something breaks, everything prior to it has happened. ChrisA
That makes sense. As Guido mentioned, this is similar to reusing a variable in a for-loop. You do it at your own risk. Ok consider me convinced. I will use the following sentence to explain name binding in partial matching: “Match statements are liable to any or all names bound in any of the patterns used, and your code is incorrect if you aren't prepared for that."
On 14 Feb 2021, at 7:20 PM, Chris Angelico <rosuav@gmail.com> wrote:
On Sun, Feb 14, 2021 at 11:26 PM Abdulla Al Kathiri <alkathiri.abdulla@gmail.com <mailto:alkathiri.abdulla@gmail.com>> wrote:
My idea was that in the case of partial matching or full matching without passing the guard, the binding names has some sort of self destruction and return to the previous state. Using different variable names would resolve the issue and if I want to modify the global variables, I could choose to do so in the case block after the case succeeded. At least, this way, it would be more explicit, conveying the person intention (or forgetting if the original global value was later needed). I saw many people online talking about this the last couple of days so I thought I would bring it up here. Any other syntax variant could be used to achieve the same thing.
It's not about syntax. Python doesn't have an idea of "self destruction and return to the previous state". The nearest equivalent is a very special case at the end of an exception handler, where after "except Exception as e:" you'll get an implicit "e = None; del e" to prevent a refloop. That's not a return to the previous state, that's a conscious clearing of one reference.
If this "unwinding" were desired, the best way would be to simply make it a permanent part of the match semantics - no syntax for selecting which behaviour you want. There's no backward compatibility to be maintained (yet). But that would be inconsistent with the rest of Python, where things happen step by step, and if something breaks, everything prior to it has happened.
ChrisA _______________________________________________ Python-ideas mailing list -- python-ideas@python.org <mailto:python-ideas@python.org> To unsubscribe send an email to python-ideas-leave@python.org <mailto:python-ideas-leave@python.org> https://mail.python.org/mailman3/lists/python-ideas.python.org/ <https://mail.python.org/mailman3/lists/python-ideas.python.org/> Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/5K65WY... <https://mail.python.org/archives/list/python-ideas@python.org/message/5K65WY7B6O7EO5ZKWZZCS3OYV2HCIBQJ/> Code of Conduct: http://python.org/psf/codeofconduct/ <http://python.org/psf/codeofconduct/>
I should add that I accidentally left out a word. It should be “... liable to *overwrite* any or all names ...” On Sun, Feb 14, 2021 at 12:10 Abdulla Al Kathiri < alkathiri.abdulla@gmail.com> wrote:
That makes sense. As Guido mentioned, this is similar to reusing a variable in a for-loop. You do it at your own risk. Ok consider me convinced. I will use the following sentence to explain name binding in partial matching: *“Match statements are liable to any or all names bound in any of the patterns used, and your code is incorrect if you aren't prepared for that."*
On 14 Feb 2021, at 7:20 PM, Chris Angelico <rosuav@gmail.com> wrote:
On Sun, Feb 14, 2021 at 11:26 PM Abdulla Al Kathiri <alkathiri.abdulla@gmail.com> wrote:
My idea was that in the case of partial matching or full matching without passing the guard, the binding names has some sort of self destruction and return to the previous state. Using different variable names would resolve the issue and if I want to modify the global variables, I could choose to do so in the case block after the case succeeded. At least, this way, it would be more explicit, conveying the person intention (or forgetting if the original global value was later needed). I saw many people online talking about this the last couple of days so I thought I would bring it up here. Any other syntax variant could be used to achieve the same thing.
It's not about syntax. Python doesn't have an idea of "self destruction and return to the previous state". The nearest equivalent is a very special case at the end of an exception handler, where after "except Exception as e:" you'll get an implicit "e = None; del e" to prevent a refloop. That's not a return to the previous state, that's a conscious clearing of one reference.
If this "unwinding" were desired, the best way would be to simply make it a permanent part of the match semantics - no syntax for selecting which behaviour you want. There's no backward compatibility to be maintained (yet). But that would be inconsistent with the rest of Python, where things happen step by step, and if something breaks, everything prior to it has happened.
ChrisA _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/5K65WY... Code of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/LQWGSE... Code of Conduct: http://python.org/psf/codeofconduct/
-- --Guido (mobile)
participants (3)
-
Abdulla Al Kathiri
-
Chris Angelico
-
Guido van Rossum