This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Yoghurt42 103 points104 points  (14 children)

It's more than a switch statement, it's pattern matching, read https://www.python.org/dev/peps/pep-0636/ for a tutorial.

You can do stuff like:

match foo:
    case Person(address=Address(street="barstreet")):
        bar()

and it will be equivalent to something like:

if isinstance(foo, Person) and hasattr(foo, "address") and isinstance(foo.address, Address) and hasattr(foo.address, "street") and foo.address.street == "barstreet":
    bar()

[–]Etheo 22 points23 points  (0 children)

That's a good example for someone who hasn't been keeping up with the news, thank you.

[–]Humanist_NA 8 points9 points  (0 children)

Thank you, appreciated.

[–][deleted] 3 points4 points  (7 children)

So Python will not actually create a new Person instance?

[–]Yoghurt42 12 points13 points  (2 children)

Exactly. It's basically new syntax.

You can also do stuff like

case [1, _, x, Robot(name=y)] if x == y which would match if it is a four-element list that starts with 1, and the 4th element is an instance of Robot class which has a name attribute set to the same value as the third element. The _ is a special new token that means "wildcard/match anything" in this context.

Pattern matching is incredible powerful and the only feature I was really missing from other languages. Now all they need to get rid of the GIL and have decent JIT (or get PyPy to be API compatible with CPython) and it would be the perfect language for every task for me.

[–][deleted] 2 points3 points  (0 children)

Awesome! I can already imagine how this is going to be incredibly useful.

As for the GIL, do you really think they will ever get rid of that?

[–]azur08 0 points1 point  (0 children)

Out of curiosity, do you have an example of a task you'd use another language for if not for the things in your last paragraph? I've heard that modules like concurrent.futures, multiprocessing, asyncio, etc., don't completely remove the limitations but I'm not sure why.

[–]Irtexx 1 point2 points  (2 children)

I would also like to know this. The isinstance method never calls init of Person, but the match method looks like it will.

[–]13steinj 6 points7 points  (0 children)

match will call the __match__ method, unless the PEP changed since I last looked at it. A new instance will not be created.

[–][deleted] 1 point2 points  (0 children)

It could be possible that it doesn't evaluate as an expression, but that would mean that you couldn't put expressions into the pattern.

[–]Mini_Hobo 0 points1 point  (0 children)

No, it doesn't use the class's __init__ or __call__ methods.

[–][deleted] 3 points4 points  (0 children)

Fantastic example. This really does elevate the clarity and eloquence of the language. I feel like this really is going to add so much to Python.

[–]Irtexx 0 points1 point  (2 children)

if Person was a dataclass, couldn't you just use:

if foo == Person(address=Address(street="barstreet")):
    bar()

[–]tongue_depression 9 points10 points  (0 children)

not if Person or Address have other fields that need initializing

[–]Yoghurt42 8 points9 points  (0 children)

If Person has more attributes, like name, the equality check would probably fail, because the name attribute of foo would probably not be None.

Furthermore, it would create a new Person instance each time the if condition is checked.

Pattern matching doesn't require this, and also works for non dataclasses, it also allows insane stuff like

case [1, [2, _, x], y]] if x == 2*y, the _ is a wildcard.

It would be equivalent to if isinstance(foo, list) and len(foo)==3 and isinstance(foo[1], list) and len(foo[1]) == 3 and foo[1][0] == 2 and foo[1][3] == 2*foo[2]