Hacker News new | past | comments | ask | show | jobs | submit login

Perl smart match IS a disaster, we fought with lot of bad smart-match behavior for a while in the late 2000s, then educated programmers over and over on how to do smart matching just to see how the Perl community and the language took action to deprecate most of it. We then dove into 100k+ lines of code to remove all smart matching entirely, including all `when` clauses. To me that's the definition of a disaster for a programming language.

Pattern matching is a can of worms in the way people think these should work and the way compilers implement them. It holds unexpected behavior in so many ways and it's not at all about language abuse, but about giving a tool that is prone to misunderstanding and flimsy enough for programmers to shoot themselves and others in the foot. And it's not the same pattern matching in Haskell (which is fine) that it is in ES (where it's not).

Fortunately the TC39 proposal looks somewhat stalled and you can already see in the Babel plugin and proposal discussion questions on why or how this does or does not do behavior X, Y or Z or how syntax should be implemented. This is a bad sign on how pattern matching can be confusing, but then maybe this may be a sign it never gets past stage 1. Here are a few soundbites from the proposal:

     when true        -> ... // ok, if x === true
     when undefined   -> ... // not ok, this creates a local var called "undefined"
     when Infinity    -> ... // ok, if x === Infinity
     when -Infinity   -> ... // Syntax error!
     when /.*/        -> ... // not ok, unsupported, surprise surprise.
     when {x} = {x:1} -> ... // great, we check if x exists and set a value on it if it doesn't?!?!
     when {status = 200} if (status === 200) -> ...   // left as an exercise for the reader
Now I just love this one, as it just subsumes many of my concerns:

     const y = 2;
     case (1) {  // matching on a value itself, lovely
         when y if (y === 2) -> 'does not match', // y is (re)created locally for the if!
         when x if (x === 1) -> 'x is 1'  // you're a psycho if you write code like this
     }
Now, I must confess I do like matching on types as they can substitute method dispatching elegantly and should be simple to understand and implement, but this is more suited for typed languages, not ES. Same for basic parameter existence as a destructuring dispatch for arrays and objects. But never on value, ranges (`[1..=x]` - yuck, Rust!) or anything more complex.



Perl smart match was a disaster because it was symmetric.

Historically, smart match in Perl was "stolen" from the ideas of Perl 6. Perl 6 (now named Raku https://raku.org using the #rakulang tag on social media) learned from the problems found in Perl, and changed its smart-matching model from symmetric to asymmetric. Basically, `a ~~ b` is syntactic sugar for `b.ACCEPTS(a)`. By transferring the responsibility for what smart matching means to an object of a given class, made it possible to make much more sane default behaviour, as well as allowing authors to define their own smart-matching behaviour for custom classes.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: