In general, the code <type>(arg1=value1)
is changed to the code <type>(attr1=value1)
during a case
in a match
statement. This allows for some very interesting and complex capturing.
For example, we can ask "does my instance have a attr called 'sort', if so capture it":
match [1,2,3]:
case list(sort=f): # this isn't a call, it is an attr-capture statement
print(f)
Since the first (and only) positional argument of the list instance is the list values, you can capture those items as well:
match [1,2,3]:
case list((x,*y),sort=f): # here we are capturing the 'attr' called 'sort' as 'f'
print(x,y,f)
Likewise, you can specify the matching values instead of capturing them into variables:
g = list.sort
match [1,2,3]:
case list((1,*y),sort=g): # here we ask if the attr 'sort' is the same as 'g'
print(y)
However, I am now confused by the following:
match [1,2,3]:
case list(x,sort=list.sort): # fails to match, but why???
print(x)
I would have thought that this fails because list.sort
means something different than to specify "the function 'sort' of 'list'". Maybe sort=list.sort
means "do I have an attr called 'sort' which itself is of 'type' 'list' that also has an attr called 'sort'". So I tried:
match [1,2,3]:
case list.sort: # also fails, why?
print('ya')
So, list.sort
does not mean that I want type list with an attr of sort. So, then I tried:
match list.sort:
case list.sort: # does match, wait, what?
print('ya')
Which works. So, list.sort
during a case
does mean to use the function of sort
from the type of list
, but then why did list(sort=list.sort)
fail?
Example of capturing an attr 'y' and matching an attr 'x':
class P:
def __init__(self,a,b):
self.x,self.y = a+b,a-b
match P(5,6):
case P(x=11,y=a): # a is a new variable, 11 is a match
print(a)
list.sort
is a descriptor, so it's not going to match sort=
which will be a method or function.
You can see the type of f
is a built-in method:
match [1,2,3]:
case list(x,*y), sort=f): # inspect the capture of `sort` as `f`
print('match', f) # match <built-in method sort of list object at 0x104d94c80>
But the type of list.sort
is not:
>>> type(list.sort)
method_descriptor
>>> list.sort is [1,2,3].sort
False
But if you use the method from the same list instance, this works:
foo = [1,2,3]
match foo:
case list((x, *y), sort=foo.sort):
print('matched')
But this doesn't make much sense to me to match on the sort
attribute, as it's different for each instance of a list:
>>> x = [1,2,3]
>>> y = [1,2,3]
>>> x.sort is y.sort
False
>>> x.sort == y.sort
False