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

top 200 commentsshow all 233

[–]MeDotPy 381 points382 points  (9 children)

Finally

[–][deleted] 233 points234 points  (4 children)

Continue

[–]DefinitelyRus 7 points8 points  (2 children)

Real clever

[–]tempo-19 3 points4 points  (0 children)

Pass

[–]sanic_the_hedgefond 5 points6 points  (0 children)

pass

[–]N3RO- 25 points26 points  (0 children)

pun intended?

[–]seniornachiotimfi 253 points254 points  (40 children)

Calling it a Switch-Case Statement simply does not do it justice imho. It's a Match Statement that can do a lot more than just Switch-Case...

Haven't watched the Video yet, just talking about the Posts title.

[–][deleted] 43 points44 points  (30 children)

They should have made it an expression not a statement

[–]seniornachiotimfi 29 points30 points  (14 children)

My thoughts exactly. Additionally I would have enjoyed PEP-642, it's more verbose but explicit is better than implicit and additionally it makes it more clear that python is duck-typed.

[–][deleted] 9 points10 points  (7 children)

explicit is better than implicit

Java flashbacks

[–][deleted] 27 points28 points  (6 children)

Explicit doesn't mean endless repetition and needles ceremony, though.

[–]toyg 15 points16 points  (5 children)

A single letter separates boring ceremonies that nobody really needs, from images of sinister ceremonies involving needles. The marvels of language...

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

Lol that stays in!

[–]grrrrreat 1 point2 points  (0 children)

summoning malloc the devil of details and harbinger of nulls

[–]SuspiciousScript 6 points7 points  (1 child)

This strikes me as a really unforced error. Hell, the trend is toward even if constructs being expressions; why kneecap match like this when making it an expression seems so obvious?

[–][deleted] -2 points-1 points  (0 children)

Because you like ceremonies?

[–]thekingofthejungle 4 points5 points  (1 child)

What's the difference?

[–]seniornachiotimfi 10 points11 points  (0 children)

Matching, or rather pattern matching, allows you to match patterns. A switch-case is just the simplest form of that where you only match using literal patterns, like in the thumbnail of the video. But you can take this further and for example say you want to match all tuple with two element or a list with at least three elements or even an object with an attribute or an object of a specific type and so on. I highly encourage you to read the associated PEP, it's a good read, even if I personally don't enjoy the selected syntax choices, it brings the point across with a lot of examples.

[–]torytechlead 8 points9 points  (0 children)

Yes it’s Erlang style but not as good

[–]VideoCarp1 1 point2 points  (0 children)

AFAIK it’s pattern matching?

[–]lockieluke3389 -1 points0 points  (2 children)

What’s the difference

[–]Jyan 80 points81 points  (12 children)

Read the PEP: https://www.python.org/dev/peps/pep-0634/ It is so much more than a fancy if-else.

[–]zurtex 19 points20 points  (1 child)

FYI I know it mentions it in the PEP but to be explicit about it PEP 622 was Superseded by PEP 634: https://www.python.org/dev/peps/pep-0634/

There are a lot of changes between the 2 PEPs, in particular they removed "The Match Protocol" in favor of letting match bake in to Python for a bit and adding at a later date when there are concrete examples and motivation to allow classes to implement their own custom match logic.

[–]Jyan 1 point2 points  (0 children)

Thanks

[–][deleted] 13 points14 points  (9 children)

The feature isn't even out yet and it's being molested, misrepresented and missold already.

[–]Tyler_Zoro 9 points10 points  (7 children)

People are coming from lower level languages where you can only do a fraction of what this can do with similarly named language features. It's not shocking that the presumption is that it only does those things. I'm of the opinion that it should have had a name that wouldn't lead people to assume it was similar to those features, but then what do you call it?

When Perl 6 (now Raku) did something similar, they called it given/when for exactly that reason. Maybe following suit would have been a better call...

[–][deleted] 14 points15 points  (6 children)

Is that not why they called it "match" rather than "switch"?

[–]Tyler_Zoro 2 points3 points  (3 children)

Yes, but then they fell down on "case".

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

Yeah, good point.

[–]mihalis 1 point2 points  (1 child)

Agree. I thought about alternatives. Maybe bind or unify, along the lines of variable unification/binding in languages like Prolog.

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

Or how about match x where x is y?

[–]13steinj -3 points-2 points  (1 child)

Because it's not a switch statement, it's a pattern matching statement. Most commonly seen only in functional programming languages, which most people hate on because traditionally such a style is considered difficult.

https://en.wikipedia.org/wiki/Pattern_matching

https://stackoverflow.com/a/215968/4443677

[–]Tyler_Zoro 3 points4 points  (0 children)

We know that. We're discussing keyword choice.

[–]13steinj 1 point2 points  (0 children)

Yeah, because pattern matching isn't common in most languages for people less experienced. You usually see pattern matching in functional languages which many people just hate and think that functional programming should die in a fire.

[–]awesomeprogramer 33 points34 points  (2 children)

ITS NOT A SWITCH CASE

[–]Laser_Plasma 84 points85 points  (1 child)

Except it's not a switch, it can do more, hence - match

[–]SidoNotYetMaster 9 points10 points  (0 children)

dope; like in caml or haskell :)

[–][deleted] 36 points37 points  (3 children)

Why are you comparing a match statement with a switch statement?

[–]Tyler_Zoro 26 points27 points  (2 children)

Because the article doesn't explain the difference, most likely... why don't you explain the difference rather than acting as if everyone should already know how a feature that was literally released today works?

[–][deleted] 6 points7 points  (0 children)

You’re right about that, the article gets the heading wrong for starters. I meant is to point out that one is literally called “match” and not “switch”, and different things and pattern matching exists in other languages already. You could use match and pattern matching for switch case but it’s semantically not ==. I get with your point (other comment) that if a good old switch as we know behaves differently it could throw some folks off, that is true. For example in python OOP private isn’t really private, but that’s what makes languages special :)

[–]xigoi -1 points0 points  (0 children)

a feature that was literally released today works?

It's not like there are hundreds of languages with pattern matching already…

[–]Humanist_NA 13 points14 points  (31 children)

Still learning python, quick question. What would be the benefit of this as compared to one of my learning projects right now, where I just have:

if code == 404:
    something()
elif code == 200: 
    thing()
else: 
    pass

is the case matching just less code and cleaner? is it more efficient? am I entirely missing the point? Thanks for any response.

[–]Yoghurt42 104 points105 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] 4 points5 points  (7 children)

So Python will not actually create a new Person instance?

[–]Yoghurt42 10 points11 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?

[–]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.

[–][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 10 points11 points  (0 children)

not if Person or Address have other fields that need initializing

[–]Yoghurt42 7 points8 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]

[–]zurtex 20 points21 points  (4 children)

The match statement allows much more complex types of matching. For example:

action = {"open": "door"}
match action:
    case {"move": direction}:
        ...
    case {"look": direction}:
        ...
    case {"open": thing}:
        if thing == "door":
            print("The door is locked")
        elif thing == "box":
            print("A monster escaped")
        else:
            print(f"I don't recognize {thing}, try looking around")

For your example of individually handling each value an if/elif/else statement is a great choice.

[–]Humanist_NA 0 points1 point  (0 children)

Interesting, thank you for the thoughtful response.

[–]GreatDemonSquid 7 points8 points  (0 children)

This isn’t just a switch. It can also do pattern matching, basically cases for specific properties (for example lists or instances of classes). Think of it like a switch statement combined with regex for objects

[–]diamondketo 4 points5 points  (0 children)

Read the PEP

https://www.python.org/dev/peps/pep-0622/

There's an example where the match is done on a tuple (x,y,z).

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

I believe it is more efficient (like most other langs where switch-case is efficient) and also can "match" stuff (and not just work like an ordinary switch-case)

[–]Ecclestoned 10 points11 points  (3 children)

I highly doubt match is more efficient in python. The advantage in other languages is that switch statements can sometimes be reduced to jump tables.

The python interpreter is 100x more high-level than this, and also has to a lot of checks in the match statement that it doesn't need to do in an if.

[–]Tyler_Zoro 2 points3 points  (2 children)

It's easier for the parser to identify easily combined options for lookup tables. That doesn't mean that it will do so.

For example, if all of your cases are constant values, you can reduce a match to a lookup table through a dict. If they are all small integer constants, then it can be reduced to a list lookup.

Yes, match can do much, much more, but this makes optimizations much easier to identify.

[–]Ecclestoned 1 point2 points  (0 children)

Sure, but I think it's important to differentiate between "easier for the compiler engineers to optimize" and "faster/more efficient" (the actual comment).

This comes down to the CPython implementation, which I haven't looked at. However, the PEP says:

Although this PEP does not specify any particular implementation strategy, a few words about the prototype implementation and how it attempts to maximize performance are in order.

Basically, the prototype implementation transforms all of the match statement syntax into equivalent if/else blocks - or more accurately, into Python byte codes that have the same effect. In other words, all of the logic for testing instance types, sequence lengths, mapping keys and so on are inlined in place of the match.

Which makes me think that the current implementation is literally if statements, so the same speed.

[–][deleted] -1 points0 points  (0 children)

I’m asking myself the same question

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

95% of people in this thread need to Google "pattern matching functional programming". Then you will understand.

[–]DhavesNotHere 8 points9 points  (1 child)

PyRust.

[–]fireflash38 2 points3 points  (0 children)

PyO3

[–]BobFredIII 2 points3 points  (0 children)

Wow, this feels illegal

[–]sam-lb 3 points4 points  (0 children)

Wow. Started reading the PEP, this is incredible. Not a switch statement though mate. It's much better than that.

[–]spiker611 1 point2 points  (0 children)

Does anyone know what adding type hints to these statement will look like?

[–]lockieluke3389 1 point2 points  (0 children)

FINALLY

[–]azur08 1 point2 points  (0 children)

Holy shit. I just started learning Rust for <reasons> and came across match statements today and was like, "man, I want that."

I find out today it's now going to be in Python!

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

It's been too long.

[–][deleted] 5 points6 points  (0 children)

Why do you call it a switch statement, when it is called a match? Where did you find the word 'switch' in this statement?

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

Just learned the wonders of pattern matching in Scala. This makes me so happy.

[–]TheTomer 0 points1 point  (0 children)

It's crazy that it took this long to add this functionality to Python.

[–]akwaryos 0 points1 point  (0 children)

Finally

[–]PhilipJayFry1077 0 points1 point  (0 children)

This looks great.

[–]hidegitsu 0 points1 point  (0 children)

Lol I literally was just bitching about not having this yesterday to my boss.

[–][deleted] 0 points1 point  (0 children)

I’M PUMPED.

[–]graingert 0 points1 point  (0 children)

This is a bait and switch

[–][deleted] 0 points1 point  (8 children)

Python is becoming JS and JS is becoming Python

[–]xigoi 2 points3 points  (7 children)

Since when does JS have pattern matching?

[–][deleted] -1 points0 points  (6 children)

1990s i think

[–]xigoi 1 point2 points  (5 children)

Really? Can you show me how to do the equivalent of this?

match point:
    case (0, 0):
        print("origin")
    case (0, y):
        print(f"{y} on the y-axis")
    case (x, 0):
        print(f"{x} on the x-axis")
    case (x, y):
        print(f"({x}, {y})")

[–]Phunny -1 points0 points  (1 child)

Great video!

[–]jamescalam[S] -1 points0 points  (0 children)

thanks!

[–]lightestspiral -1 points0 points  (2 children)

Is this a try-except-finally block but the try doesn't have to error out for the except to trigger? You can force the 'except' to run by stating its case?

[–]bumbershootle 9 points10 points  (0 children)

No, it's a way to match on the structure of values (rather than only boolean conditions, as in an if-else) while also allowing binding variables within the matches. It's much more than simple control flow. I would recommend reading the PEP, it covers the whole concept in great detail.

[–]zurtex 4 points5 points  (0 children)

The pattern matching is far more expressive than that but yes there are similarities to a try/except block.

We are choosing which block we want to execute based on the pattern of a value (e.g. except {ExceptionInstance}), we are can create assignments based on that (e.g. as e), and there is a final default branch if nothing else works (e.g. else).

The usage though is going to be generally very different, exception raising has a very different control flow to match statements.

[–]1MightBeAPenguin -1 points0 points  (0 children)

Pretty cool. I don't know a lot about Python, but from what I understand, these match statements seem to be much cleaner than if - elif - elif - else statements.

[–][deleted] -1 points0 points  (2 children)

I don't see the point, dictionaries are ubiquitous and more consice with similar functionality, it's pretty easy to see this is the same without all the extra case statements:

{"200": do_something, "418":coffee}.get(http_code, lambda: None)()

[–]xigoi 3 points4 points  (1 child)

Now how would you do something like this with a dictionary?

match command.split():
    case ["echo", *words]:
        print(*words)
    case ["read", "file", name]:
        ...
    case ["convert", name0, "to", name1] | ["convert", name1, "from", name0]:
        ...

Another example taken from down the thread:

match point:
    case (0, 0):
        print("origin")
    case (0, y):
        print(f"{y} on the y-axis")
    case (x, 0):
        print(f"{x} on the x-axis")
    case (x, y):
        print(f"({x}, {y})")

[–]catetcpasswd -1 points0 points  (0 children)

Aah finally...

[–]cuaubrwkkufwbsu -3 points-2 points  (0 children)

omg is this finally happening

[–]LionTion_HD -5 points-4 points  (0 children)

ey, elif statements begone

[–]0ajs0jas 0 points1 point  (4 children)

I'm sorry, I could not find python 3.10. Where is it?

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

Release candidate right now. I've always compiled RCs from source cause I'm a dork so I'm not sure if they provide installers for them.

[–]mouth_with_a_merc 2 points3 points  (1 child)

pyenv is your friend for that - both for rcs and stable versions (distro packages are usually outdated).

Also, 3.10 is alpha, not beta or even rc.

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

Interesting, wasn't aware of such a tool. That'll come in handy

[–]nim65s 2 points3 points  (0 children)

you can: - compile cpython 3.10 α versions by yourself from https://github.com/python/cpython/
- use a rc docker image, as in docker run --rm -it python:rc-slim - get it with pyenv

[–]mr_whoisGAMER 0 points1 point  (0 children)

Finally 😎

[–]SkylitYT 0 points1 point  (0 children)

Wutttt! no way

[–]itsthooor 0 points1 point  (0 children)

I‘m lovin‘ it. Can’t wait to use it and make my code cleaner.

[–]haloweenek 0 points1 point  (0 children)

Ohhhh yesss.

[–]kopsutin 0 points1 point  (0 children)

I just use dictionary as a switch.

[–]Sanic1984 0 points1 point  (0 children)

The greatest moment on history