Can someone explain to me the history behind Python's aversion to switch statements? I get Python is opinionated and I'm not trying to start a language war, it was just never clear to me why the `if ... elif` pattern was the preferred idiom.
I think culturally, because “explicit is better than implicit” (from the Zen of Python). Switch statements have a lot of implicit-ness to them (implicit invocation of equality comparison, to start) and it never seemed quite necessary, given how spare Python syntax is anyway.
PEP 622 – Structural Pattern Matching
51–60 of 131 posts
Re: PEP 622 – Structural Pattern Matching
#52glad to see this! though it's a shame that the proposed `match/case` is a statement, not an expression: > "We propose the match syntax to be a statement, not an expression. Although in many languages it is an expression, being a statement better suits the general logic of Python syntax." no matching in lambdas unless those get overhauled too :( instead, let's get excited for a whole bunch of this: match x case A: res…
match shape:
case Square(l):
area = l * l
case Rectangle(l, w):
area = l * w
case Circle(r):
area = (PI * r) ** 2
when I want to just write this: area = match shape:
case Square(l):
l * l
case Rectangle(l, w):
l * w
case Circle(r):
(PI * r) ** 2
I'm almost guaranteed to forget (or mistype) the `area = ` at least once in any match clause of length.Re: PEP 622 – Structural Pattern Matching
#53If you're curious about why this is so useful, and reading the (quite dry) PEP isn't your thing, I would heartily recommend playing with Elixir for a few hours. Pattern matching is a core feature of the language, you won't be able to avoid using it. The language is more Ruby-like than Python-like, but Python programmers should still have an easy time grokking it. When I was getting started I used Exercism [1] to have some simple tasks to solve.
Re: PEP 622 – Structural Pattern Matching
#54So it’s actually a smart switch statement. Seems like it doesn’t create instances when you’re doing Node(children=[Leaf(value="("), Node(), Leaf(value=")")]) instead: 1. Node means "is instance of Node". 2. Everything in between () is "has an attribute with value". 3. List means "the attribute should be treated as a tuple of".. etc.. Very confusing, this definitely needs another syntax, because both newcomers and exp…
I used to feel like I could define __getattr__ or __setattr__ and understand the implications, but that's getting increasingly terrifying.
Re: PEP 622 – Structural Pattern Matching
#55Very interesting. This PEP is still in draft state, but I am interested to see how the community will react. For me, I have a few thoughts: 1) This is really close to Erlang/Elixir pattern matching and will make fail-early code much easier to write and easier to reason about. 2) match/case means double indentation, which I see they reasoned about later in the "Rejected ideas". Might have a negative impact on readabil…
> While matching against each case clause, a name may be bound at most once, having two name patterns with coinciding names is an error.
match data:
case [x, x]: # Error!
...
Which is a bit of a shame. This comes in handy in Elixir to say "the same value must appear at these places in the collection". I.e. for a Python tuple pattern `(x, y, x)`, `(3, 4, 5)` would not match but `(3, 4, 3)` would.Overall, though, I think this will be a great addition to Python. Pattern matching is generally a huge boost for expressiveness and readability, in my opinion.
Re: PEP 622 – Structural Pattern Matching
#56This is very exciting! One subtle thing which I noticed is the distinction between class patterns and name patterns (bindings). In particular, it is possibly confusing that the code `case Point:` matches anything and binds it to the value Point, whereas `case Point():` checks if the thing is an instance of Point and doesn’t bind anything.
Linters could help. You're shadowing `Point`, and because `case Point:` matches any value, if there's another case after that then something is wrong. But you can't always rely on linters.
Re: PEP 622 – Structural Pattern Matching
#57So it’s actually a smart switch statement. Seems like it doesn’t create instances when you’re doing Node(children=[Leaf(value="("), Node(), Leaf(value=")")]) instead: 1. Node means "is instance of Node". 2. Everything in between () is "has an attribute with value". 3. List means "the attribute should be treated as a tuple of".. etc.. Very confusing, this definitely needs another syntax, because both newcomers and exp…
The entire point of structural pattern matching is that structuring and destructuring look the same.
> This syntax goes against Zen: It’s implicit -- when using match case expressions don't mean what they regularly mean.
There's nothing implicit to it. The match/case tells you that you're in a pattern-matching context.
> I’m a big believer in this feature, it just needs some other syntax. Using {} instead of () makes it a lot better. Now no way to confuse it with simple equality.
Makes it even better by… looking like set literals and losing the clear relationship between construction and deconstruction?
Re: PEP 622 – Structural Pattern Matching
#58Earlier quoted context omitted.
I prefer the PEP syntax: it looks like the instanciation of the object I'm trying to match, so it makes sense to me.
That's their entire point: you're _not_ instantiating the object you're trying to match.
Using a different syntax for pattern matching loses the main point of pattern matching.
Re: PEP 622 – Structural Pattern Matching
#59If you want it today, Pampy does most of it: https://github.com/santinic/pampy Even match on Point(x, y, _)
Re: PEP 622 – Structural Pattern Matching
#60> case Node(children=[LParen(), RParen()]): Is this will create a second Node instance and compare it to node? If so, is it not less efficient performance wise than it's "counterpart" isinstance() + properties comparison? If this method is less efficient, it could be confusing, specially for newcomer. Am I missing something.
It reads like a Node instance construction, but it's actually syntactic sugar for: isinstance(node, Node) and node.children == [LParen(), RParen()]
[0] https://www.python.org/dev/peps/pep-0622/#the-match-protocol [1] https://www.python.org/dev/peps/pep-0622/#default-object-mat...