What does HackerNews think of proposal-pattern-matching?

Pattern matching syntax for ECMAScript

Language: HTML

Not sure why this is getting downvotes. Ternaries are at best a necessary evil in JSX. We'll all be rejoicing when pattern matching finally lands in JS [1].

[1] https://github.com/tc39/proposal-pattern-matching

The TypeScript type system meta programming actually does pattern matching very well, it’s just the underlying JS runtimes that can’t, there is a proposal for it though; https://github.com/tc39/proposal-pattern-matching.
The proposal for pattern matching syntax seems more akin to what they're looking for.

https://github.com/tc39/proposal-pattern-matching

https://github.com/tc39/proposal-pattern-matching

I'm not sure if it's stalled or not. But it's being discussed.

We often add promising TC39 proposals into Civet so people can experiment without waiting.

We've added https://github.com/tc39/proposal-pipeline-operator, a variant of https://github.com/tc39/proposal-pattern-matching, a variant of https://github.com/tc39/proposal-string-dedent and others.

Since our goal is to be 99% compatible with ES we'll need to accommodate any proposals that become standard and pick up anything TC39 leaves on the table (rest parameters in any position, etc.)

Pattern matching is actually being discussed in tc39 for JS as a whole (where TS reps are some of the champions, ofc): https://github.com/tc39/proposal-pattern-matching

The specifics of the proposal will likely shift a bit since it's still stage 1 (2?).

Don't be mistaken, Typescript do not has proper pattern matching support, The proposal is far from being adopted https://github.com/tc39/proposal-pattern-matching

> Related, Typescript is the only language I know of that through flow analysis does not require you to redefine the variable. E.g. you can do something like

This is called smart casting and is widely used in Kotlin

I think they are great! Especially in combination with pattern matching (https://github.com/tc39/proposal-pattern-matching), or when using JSX.
The tc39 pattern matching proposal seems to have some renewed energy with new champions (including from the typescript team) and syntax proposals:

https://github.com/tc39/proposal-pattern-matching

Also there has been movement in the user land space with libraries like ts-pattern that make use of new features in typescript 4.x to provide basically the full pattern matching experience:

https://github.com/gvergnaud/ts-pattern

Hopefully we will get real pattern-matching at some point (https://github.com/tc39/proposal-pattern-matching), but I kinda sorta like this!
At this point TS is trying to keep runtime syntax in line with TC-39 (the language committee in charge of JS) proposals that reach Stage 3 (and thus likely to reach Stage 4 and general acceptance/use in the browser).

There is currently a Stage 1 proposal for a pattern matching syntax presented to TC-39. If it reaches Stage 3 then it is presumed likely Typescript will implement it.

https://github.com/tc39/proposal-pattern-matching

> So one of your arguments is that it'll be difficult to maintain the C implementation of call_user_func, call_user_func_array and func_get_args?

No, I wasn't talking about C; or about language implementations at all. I was arguing that the phrase "just allowing named parameters" gives the impression that this feature would only affect function calls and definitions, when that's not the case. The most obvious repercussions are for `call_user_func`, `func_get_args`, etc. whose API would need to change. That induces changes to code that calls those functions, and code that calls that code, and so on.

Although PHP is famously un(der)specified, I'm talking about things like "`call_user_func(f, args...)` is equivalent to `f(args...)`"; anything relying on that property will break in the presence of named parameters (since they may be given in a different order), unless patched to take it into account.

> Whether I as a function author decide to re-order my arguments is a decision informed but not dictated by the existence of named arguments.

Sure, but that's just a first-order effect. It's a breaking change for higher order code (where functions and arguments are data, and calling is an operation on that data). That's why I gave an example of higher-order code.

As a silly analogy: if PHP extended its default numeric types to be complex numbers, that wouldn't affect existing values like `$age = 18` or `$length = 50`, since they're "informed, but not dictated by the existence of complex numbers"; it also wouldn't affect calculations using these values like `plus($age, $length)`. Yet it would have profound effects on numeric functions, which may have to be patched to take complex values into account: some functions, like `array_sum`, might work fine as-is; whilst others, like `array_slice`, might make no sense given the new situation (how might we take `3+5i` elements from an array?).

> All your "alternative" solutions read like horrible code to me compared to the now commonly accepted designs.

This sentence is a good example of what my "rant" is about. Why should improvements depend on what's "commonly accepted" (surely that's antithetical)? Could you elaborate any further on what makes those examples "read like horrible code"?

As a more detailed example we can look at `switch`: it's clearly a "now commonly accepted design", due to its prevalence in many "popular languages" like PHP/Javascript/etc. An alternative approach which solves the same problem is `match`, as used by ML. However, ML is not a popular language, and ML also introduced currying which you say "read[s] like horrible code". Does that make `switch` better than `match`?

This is an interesting example since a recent Python Enhancement Proposal is trying to add `match` to the language. This proposal seems credible, since the author list includes Guido van Rossum (the creator of Python): https://www.python.org/dev/peps/pep-0622

Perhaps this is an outlier, since Python doesn't already have an equivalent like `switch`?

I wonder if the existence of that PEP changes your opinion of `switch` versus `match`? Maybe not; after all, Python doesn't have `switch` so maybe `match` is better than nothing. What if I showed you an equivalent proposal for adding it to Javascript (using the keyword `case`, like the non-popular language Haskell)? https://github.com/tc39/proposal-pattern-matching

At what point does a feature go from "horrible code" to "stealing each others' best ideas"?

What makes this even more interesting is that the very first sentence of PEP622 makes it clear that this is a case of stealing a good idea:

> This PEP proposes to add a pattern matching statement to Python, inspired by similar syntax found in Scala and many other languages.

To add a further wrinkle, PEP3103 was rejected for proposing essentially the same idea back in 2006: https://www.python.org/dev/peps/pep-3103/

Perhaps it was too soon to adopt ideas from Scala, since it had only been out for a couple of years by that point. However, `match` wasn't invented by Scala; it's been around in multiple languages, some more popular than others, dating back to 1973!

As further evidence of this, there was another rejected PEP for the same basic idea, from way back in 2001: https://www.python.org/dev/peps/pep-0275

I wonder whether your line of reasoning would come out in in favour of PEP622 today, whether it would have come out in favour of PEP275 twenty years ago, and whether it will argue in favour of `match` twenty years from now?

For reference, the proposal: https://github.com/tc39/proposal-pattern-matching

Rust’s pattern matching is deliberately fairly limited in what it can do; it’s all about destructuring types, not running arbitrary code like Perl’s smart-match (which even so I would not describe as a disaster). It’s conceptually very clean—arguably simpler than what ECMAScript already has. `let PATTERN = EXPRESSION;`, `if let PATTERN { … }`, `match EXPRESSION { PATTERN => … }`, `fn NAME(PATTERN: TYPE)`, &c., everything that can introduce a new binding is a pattern. Some of the uses of patterns are refutable (match branches, `if let`, `while let`), and some irrefutable (`let`, `for`, function arguments, closure arguments).

ECMAScript already has destructuring in various places, corresponding to irrefutable pattern matching; what the proposal’s `case` expression introduces is essentially just refutable destructuring, plus a smidgeon of expression-orientation (`->` corresponding to `=>`, that `case` is an expression that yields a value, rather than a statement) in a place that sorely needs it. This is a very logical extension of the language.

If TC39 or equivalent were to design a new language to actively replace JavaScript (meaning something that all extant JavaScript code should be able to migrate to easily, preferably automatedly), there is no doubt in my mind that the language would be more expression-oriented than ECMAScript is, that destructuring syntax would be brought in line with what we call pattern matching so that there was one coherent concept underneath (probably called pattern matching), and that `switch` would use it, becoming equivalent to this proposal.

The way people use JavaScript these days, these things are useful.

(I write all this as an expert and heavy user of both Rust and JavaScript; I use JavaScript more, most of the time, but prefer Rust. Rust was the first language I learned with each of algebraic data types, pattern matching and expression orientation.)

Too bad pattern matching implementations in C# (possibly in JS [1] and other languages [2]) don't go beyond basically matching in switches and maybe perhaps somwewhat inside function bodies.

One of the greatest powers of pattern matching comes from being abole to match in function definitions. The simplest example:

  fac(0) -> 1;
  fac(N) when N > 0 -> N*fac(N-1).
This makes a lot of code much more readable and more concise.

[1] https://github.com/tc39/proposal-pattern-matching

[2] http://cr.openjdk.java.net/~briangoetz/amber/pattern-match.h...

Now if we could just get pattern matching[1] and optional chaining[2], that would really elevate things.

[1] https://github.com/tc39/proposal-pattern-matching

[2] https://github.com/tc39/proposal-optional-chaining

It's getting there for us in JS land, slowly but surely! There's still a lot of discussions that need to happen (read as "mostly bikeshedding" IMO), but once they settle on the actual syntax, i'd feel comfortable to start using it with compilers.

https://github.com/tc39/proposal-pattern-matching

No thread on HN would be complete without the JavaScript programmer jumping in to "well actually" your response, so I formally nominate myself to fill that role. ECMAScript is getting pattern matching! It's currently a stage 1 proposal with backing from Microsoft, npm, and Facebook.

https://github.com/tc39/proposal-pattern-matching

The sample code is fine for JavaScript, but it begs to be written using pattern matching, like that in Elixir/Erlang. If you have the current state and an event to apply to that state (similar to Redux), you can pattern match on pieces of the current state and the event to apply to that state. Your event handler could look like:

``` def handle(%{state: "open", balance: balance},%Deposit{amount: amount}) do {:ok, %{state: "open", balance: (balance + amount)}} end

def handle(%{state: "closed"}, %Deposit{}) do {:error, "invalid action: account closed"} end

```

Every state/event pairing is explicitly defined as a variation of the `handle` method. There are countless ways to build a state machine like this, but the basic pattern matching primitive seems to simplify this a lot.

An extension to javascript to support this has been proposed, I'm hopeful that it gets considered seriously: https://github.com/tc39/proposal-pattern-matching

TC39 published its stage 0 proposal for pattern matching in ECMAScript a couple of days ago: https://github.com/tc39/proposal-pattern-matching