Hacker News new | ask | show | jobs
by mdrachuk 2186 days ago
So 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 experienced devs will be prone to read it as plain `==`, since that's how enums and primitives will be working.

This syntax goes against Zen: It’s implicit -- when using match case expressions don't mean what they regularly mean. It’s complicated -- basically it’s another language (like regex) which is injected into Python.

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.

  match node:
    case Node{children=[{Leaf{value="(", Node{}, ...}}
7 comments

It's worth noting that there's a truly massive amount of precedent in other languages for Python implementing it using the syntax as proposed. Languages that have or are planning to include pattern-matching where the pattern syntax exactly mirrors the expression syntax like this include Rust, Swift, OCaml, Haskell, C++, Ruby, Erlang, and many, many more.

I understand the worry that newcomers might struggle, but I don't think it's going to be the case: newcomers regularly learn the languages listed above without stumbling across that problem. And if Python did choose a syntax like the one you're proposing, it'd also be the odd one out among dozens of mainstream languages including this feature, which I think would be even more confusing!

Yes I think thats what the original commenter was missing. Pattern matching is not new ( but it is awesome ), there are already expectations of how it would look in Python.

I can't wait for this feature!

> Very confusing, this definitely needs another syntax

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?

At the current rates, it seems like it's only going to be another 5 years or so before Python is straight-up a more complicated language than Perl 5. What it lacks in frankly bizarre corner cases it's going to make up for in subtly bizarre corner cases.

I used to feel like I could define __getattr__ or __setattr__ and understand the implications, but that's getting increasingly terrifying.

Pattern matching is implemented as syntaxic sugar on top of if/else in the bytecode.

Behavior doesn't change at all.

Uhhh... yeah but that's true of almost every language feature, right? I love pattern matching but I think the point is that Python risks turning into a "kitchen sink" language with too many syntactical forms to keep in ones head if this continues.
I'm sure I think of a dozen python syntax trick most python devs do not not exist.

Python is good enough without them that they never had to learn them.

In fact, today I'm teaching "advanced python" to someone that has been coding in python for a year.

This person didn't know about list comprehensions.

I would not worry about that.

Sorry, are you trying to argue for or against the proposition that Python is on track to be straight-up more complicated than Perl 5 at this rate? Your tone suggests you think you're arguing against it, but all the evidence you're bringing is for the proposition.
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.
I know.

It doesn't bother me since I see that match/case is a whole different context, I know I'm matching, and have no reason to instanciate anything here.

But since Foo(a=1) looks like instanciation, it's obvious to me what it's supposed to match.

I think that's one of the things that motivated to:

- use new keywords, but existing ones like "as", nor symbols;

- force 2 levels of indentation despite the cost of it.

This makes it very clear, with little effort, that the context is completly different.

It will make scanning the code easy, and avoid confusion.

Pattern matching traditionally resembles instantiation except potentially with wildcards, because the “pattern” in “pattern matching” is a object representation template in the same representation used elsewhere in the language.

Using a different syntax for pattern matching loses the main point of pattern matching.

And the counter-point is: you learn one time that it's not instantiation and remember it forever, and you get to resume reusing/overloading muscle-memory syntax to get the job done.
I would say it's not a smart switch statement, since you can bind variables.

  match shape:
    case Point(x, y):
        ...
    case Rectangle(x, y, _, _):
        ...
  print(x, y)  # This works
I would prefer something like:

    match node:
        on (time _ 1 @ 0, foo _ 2, bar _ 3, baz _ any, status _ 1 @ -1):
            do_something()
            rematch do_something_2(foo)
'_' indicating span, and '@' indicating position of the first item. Both can be omitted.
At first glance I like your suggestion better. It's really distinct from instantiation and won't lead to confusion (imo).