17 ms·
JavaScript Pattern Matching Proposal
- _sdegutis 8y agoI'm not familiar with the JS proposal process. Is this likely to become an official feature now that it's been proposed? If so what's the usual timeline of that look like? I would love to have this feature ASAP in the browser and/or Node.js and am eager to find out when that will be possible.
- Axnyff 8y agoThis should help you: http://2ality.com/2015/11/tc39-process.html http://2ality.com/2015/11/tc39-process.html Basically, it's just a proposition for the moment, there's no telling if that's gonna be in the language or not. It's only at stage 2 that it is likely that the feature will be added in the language.
- simlevesque 8y agoSomeone will surely do a Babel plugin to use the syntax allowing you to try it before it becomes an official feature.
- maxmcd 8y agoLinked in the readme: https://github.com/babel/babel/pull/7633 https://github.com/babel/babel/pull/7633
- Already__Taken 8y agoIt's at the bottom of the proposal https://github.com/babel/babel/pull/7633 https://github.com/babel/babel/pull/7633
- WorldMaker 8y agoRight now this says it is a Stage 0 proposal, or "Strawman". It's to see if there is interest in the committee to pursue it. So it's hard to tell the likelihood if it will show up in browsers/Node just yet. The TC39 process: https://tc39.github.io/process-document/ https://tc39.github.io/process-document/
- soccergee 8y agoYeah, I think that's essentially the idea. However the longer part is getting the support native in the browsers. Tools like babel will most likely provide some form of support before the browser does.
- habitue 8y agoThis is a Stage 0 proposal. Basically it means somebody with a connection to the TC39 (the committee in charge of the JavaScript standard) has thought this was a good enough idea to put together into a proposal. In terms of chances of standardization, that's a step up from "Hey, I have a great idea", buy there are plenty of Stage 0 proposals that go nowhere because they lose steam. I think the metric they look for is who is using the Babel plugin for it. If people are doing that, then they it has a better shot of progressing. Stage 4 is the "this is getting standardized next time" stage
- pjmlp 8y agoEven Stage 4 isn't granted it will end up on the standard, some proposals have died on Stage 4.
- shados 8y agoAny example? Since stage 3 is roughly "request for implementers", and Stage 4 requires 2 real world implementations and essentially mean "will be part of the standard in the next wave". The closest thing I can think of is ES6 modules, because the module loader spec wasn't finished, but the syntax still lived on. Now, stuff getting kicked down from Stage 3, that has happened.
- pjmlp 8y agoI was wrong, on my mind I was thinking SIMD has been dropped during stage 4.
- chunkyslink 8y agoCould someone please explain what this could be used for ?
- _sdegutis 8y agoBasically simplifying and shortening a ton of common patterns of code, very similarly to how the new-ish destructuring syntax did a few years ago.
- dvdhnt 8y agoSo, there are example use cases in the proposal [1]. I think it's meant to standardize how we handle conditional inputs or shapes of inputs (some people use if statements, some switch, and others store it all in an object and use keys). 1. https://github.com/tc39/proposal-pattern-matching#motivating-examples https://github.com/tc39/proposal-pattern-matching#motivating...
- soccergee 8y agoSmooshes the evaluation of an object that can be many different shapes into an easy to understand operation. I think the HTTP response is a great example. It can have many status codes which can determine how you want to proceed with that response. If you've worked with handling HTTP responses, you've most likely implemented some version of a 'match' operation before.
- codedokode 8y agoIs not `switch` enough for this?
- cevn 8y agoIt's more concise than switch, as well as more powerful (can destructure objects). You can't set things equal to the result of a switch. I find the pattern very convenient. let day; switch (date) { case 1: day = "mon"; break; case 2: day = "tues"; break; default: day = "wed"; break; vs let day = match(date) { 1 => 'mon', 2 => 'tues' }
- JONBRWN 8y agoI should note, this isn't my proposal. Just found it interesting enough to share
- soccergee 8y agoThanks for sharing.
- m0meni 8y agoPattern matching seems to be very trendy/popular right now. It's a big jump from JS, but https://reasonml.github.io https://reasonml.github.io has very nice pattern matching that you can use, and it integrates with the JS ecosystem very nicely.
- adamnemecek 8y agoIt's been "trendy" since the 70's. It's more that more people have experience with it and realize that pattern matching is like conditional statements on steroids.
- m0meni 8y agoFair point. What I was trying to express was that it seems like the JS ecosystem has really been pushing and encouraging functional programming in a big way, which speaks to your idea that more people have experience with it.
- lmm 8y ago> It's been "trendy" since the 70's. It's been possible since the '70s but I've seen a lot more talking about it in the last 5-10 years.
- stiGGG 8y agoYeah, this applies to all that old Lisp features.
- _delirium 8y agoI think of full-featured pattern matching as a fairly recent addition even to Lisp. Lisp has had some pattern-matching constructs forever of course (cond, destructuring-bind, Norvig's sexp matcher from PAIP [1], etc.). But it's only with the more recent emergence of optima [2] as a de-facto standard that it now has really good pattern matching. It was probably the #1 thing I missed in Lisp, after having used ML a bit, until optima came along. [1] https://github.com/norvig/paip-lisp/blob/master/lisp/patmatch.lisp https://github.com/norvig/paip-lisp/blob/master/lisp/patmatc... [2] https://github.com/m2ym/optima https://github.com/m2ym/optima
- codedokode 8y agoWhat an ugly syntax. They should follow switch/case syntax for consistency.
- Analemma_ 8y agoPattern matching doesn't work the same way as switch/case though. Using that syntax would be misleading and confusing.
- k_ 8y agoWhy not? In Haxe (a statically typed language which compiles to js, amongst other targets) pattern matching happens in a switch: https://haxe.org/manual/lf-pattern-matching-structure.html https://haxe.org/manual/lf-pattern-matching-structure.html
- maemilius 8y agoI think there's an argument to be made that switch statements already do something adjacent to pattern matching. At the least, it's close enough that something like: switch(expr) { case 'foo': break; case { foo: bar }: break; } Wouldn't strike me as all that strange. It just shifts the semantics from "are you exactly this" to "do you look like this". For non-object primitives (e.g. string or number), I don't think those two things are functionally different. Granted, it doesn't help make switch any easier to learn, but I _do_ think it makes switch more _rewarding_ to learn. Right now, switch is basically just a restrictive, potentially terser version of an if statement. This would make switch actually useful to learn. It might even allow us to add some more semantics to switch over time (e.g. constructor matching with something like 'case Number'). (EDIT: thanks to armandososa for teaching me a new thing!)
- armandososa 8y agoYou'll need to insert a newline and 2 spaces before a code block to be recognized as such: switch(expr) { case 'foo': break; case { foo: bar }: break; } https://news.ycombinator.com/formatdoc https://news.ycombinator.com/formatdoc
- lolive 8y agoIsn't pattern matching interesting only in a strongly typed environment where the compiler can statically check that you are giving instructions for all possible cases?
- lmm 8y agoNo, not at all. E.g. Erlang is built around pattern matching as a core feature even though it's an untyped language.
- lightbyte 8y agoHowever Erlang does include a static analyzer (dialyzer), which every production system should be using.
- jerf 8y agoErlang was built from the ground-up with pattern matching in mind, so it works. Instead objects are jammed into the pattern matching system, and where the two disagreed, pattern matching won. (Indeed, Erlang doesn't really even have objects, just some object-like convention.) In a language that started with an object model that has grown a lot of features, trying to jam pattern matching into it after the fact grows a lot of corner cases fast. For instance, consider: a = {x: 1} a.toString = function() { return "magic: " + this.x } Should a pattern match with the string "magic: 1"? Well... probably, because it turns out that "magic: 1" == a is true. But if we do that, how does the pattern match tell a is not in fact a string, if we want to do that? You can answer that question, but the answer will raise further complications of its own. Or you could build a pattern match system around ===, which will raise its own issues. And goodness help the pattern matching syntax if it decides that both are too useful to ignore (a defensible position) and now the syntax needs to support both.... I'd say this proposal is about 10 times too short to be useful, and by the time it's long enough to be useful, it'll be clear that almost nobody will want to learn how to take the already sloppy Javascript equality situation and then learn how to lay down a pattern matching language on top of that. By contrast, since Erlang was built on pattern matching from day one, = and == have almost no such questions about them. It is very clear what they do. I did have to check what 1 == 1.0 was, even after years of use of Erlang, since I never used floating points in Erlang to speak of. (It is true, which technically I find a bit weird. I'm not sure there's another example of values of different types that can be equal. Note "" == [] because double-quotes are defined as producing lists and strings aren't actually a type, so that's not an exception.)
- d--b 8y agoJavascript is such a mess, this proposal looks really bad, and the guys discussing it are saying things like: "we should make sure that this doesn't look like anything else, so that people who learn the language don't confuse match and switch..." There is also a lot of "we shouldn't break that" messages, and people reply with "oh we already screwed that up here and there, so it's fine"...
- 11235813213455 8y agoahh, the classic JS bashing from a dotnet or Java or PHP or Ruby or Python dev, or just by ignorance
- ealhad 8y agoIt looks pretty much exactly like the Rust match, though. https://doc.rust-lang.org/stable/book/second-edition/ch06-02-match.html https://doc.rust-lang.org/stable/book/second-edition/ch06-02...
- Dibes 8y agoas someone who only has a little experience with pattern matching, how does this look bad? The syntax looks good enough to me that I could and would want to use it.
- ealhad 8y ago“looking bad” is a really subjective thing. Here is the syntax for different languages: - Rust https://doc.rust-lang.org/stable/book/second-edition/ch06-02-match.html https://doc.rust-lang.org/stable/book/second-edition/ch06-02... - Haskell http://learnyouahaskell.com/syntax-in-functions http://learnyouahaskell.com/syntax-in-functions - Scala https://docs.scala-lang.org/tour/pattern-matching.html https://docs.scala-lang.org/tour/pattern-matching.html
- ryanmarsh 8y agoI don't understand what all the fuss is about. Just looking at the syntax examples given, it looks really nice and I would jump at the opportunity to use it.
- simonw 8y agoI really like this. The syntax looks a little weird at first, but it's actually a very nice complement to modern JavaScript's object destructing mechanism: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- googlemike 8y agoOut of the major, popular languages today, Javascript is easily the worst.
- reitanqild 8y agoDon’t disagree, but what an odd place to state it. It's almost like you want to argue with js programmers.
- pitaj 8y agoFlame bait on HN is discouraged and could eventually get you banned.
- sakuronto 8y agoInterestingly, the match construct is an expression, which I don't think JavaScript has m/any of. Perhaps they could retroactively make if/else expressions, if that doesn't break back-compat.
- cevn 8y agoThat would be really cool. This match feels a lot like Rust's which is good.
- c0nfused 8y agoI would argue that it doesn't feel like JavaScript much which seems bad.
- irrational 8y agoI'd argue they've already started going down the "doesn't feel much like JavaScript" road when they started introducing things like fat arrows. I agree that it is bad.
- goatlover 8y agoAlong with the class syntax (however convenient, JS is not a class-based language). Aren't decorators also in the works?
- kristiandupont 8y agoWhy? To me it seems pretty aligned with the "feel" of destructuring.
- c0nfused 8y agoIn my mind there are several valid options out there now: 1. Regex style: new match(input, options); or built in function match(foo, bar); or like switch match (foo){ cases } But, to have the switch statement syntax and return a value seems like a less than good way to implement this.
- cshepp 8y agoPattern matching would be a great addition to JS. I built a pattern matching library[1] with a very similar syntax back in 2015 (although I will be the first to admit that it's a naive implementation). It makes validating/traversing deeply-nested objects much less verbose. I'm excited to see where this proposal goes. [1] https://github.com/cshepp/Kasai https://github.com/cshepp/Kasai
- m0meni 8y agoNice library! This actually looks great. The syntax is a bit noisey, but tbh not any more than the actual proposal.
- c0nfused 8y agoI rather like your syntax compared to the proposed version. It is less concise but must more consistent and parsable: return match(user, [ [{first: $, middle: $, last: $}, (f, m, l) => f + ' ' + m + ' ' + l], [{first: $, last: $} , (f, l) => f + ' ' + l], [_, 'unknown'] ]);
- sloanesturz 8y agoI think that this is not always guaranteed to work, because {first: $, middle: $, last: $} is the same as {first: $, last: $, middle: $} ... so calling Object.keys() is not necessarily going to use a consistent ordering. I think that is why they have to use the more verbose syntax in the other library. I think you could do something like: {first: $.0, middle: $.1, last: $.2}, (f, m, l) => ... pretty easily, though.
- z3t4 8y agoStop using (nested) ternary operator's ! Use if-statements! if(val==1) var res = 1; if(val==2) var res = 2;
- 11235813213455 8y agoYou're joking right? first: `var` is completely outdated, second: it should be `else if` for the next conditions, and third: ternary, nested or not, is simply better for that
- Kerrick 8y agoThere's real value in the fact that ternary operators form expressions, which if statements don't.
- z3t4 8y agoCould you elaborate ? I think the only difference is readability, where I favor if-statements over expressions.
- Epenthesis 8y agoExcept ternary expressions have the huge advantage that they allow assigning to const. Eg: const var = val == 1 ? 1 : va1 == 2 ? 2 : null;
- z3t4 8y agoIt's hard to argue about not using const, but can you remember any time where const actually prevented a bug !?
- bastawhiz 8y agoI can only see this being a foot gun. Deep equality testing of objects is going to encourage the use of getters. Getters with side effects (no way to prevent them) will basically ruin your day if you try to use pattern matching with them. Additionally, this would be the first "native" way to do deep equality testing of objects. I can see it being abused to do simple one-off checks that could otherwise have been done more simply in an imperative way. Do we really need to save the five lines of code at the cost of new syntax? This doesn't seem to prevent any significant amount of toil, since it can be pretty easily unrolled into existing JS syntax.
- timhwang21 8y agoI wouldn't necessarily say it's deep equality, it's just a less verbose way of sequentially checking properties. It's not going to check every property. At least for me, I feel I'd be using this a lot for the boring but common use case of checking for empty arrays and such: const doSomethingToArr = arr => match (arr) { [] => whatever, [x] => whatever, [x, ...xs] => whatever }
- karmajunkie 8y agoI'm guessing you've not worked with pattern matching of the kind you see in F# or Elixir before? Yes, JS would definitely be better off having this available. Well-developed pattern matching can actually obviate the need for conditionals in a lot of cases, which makes for far cleaner code.
- heretoo 8y agoIf it is five lines of code vs. one line of code, and we believe that the number of bugs is proportional to the number of lines of code, irrespective of which language we are programming in, then this would be an obvious benefit. And it isn't four lines saved, but four lines times the number of uses in the entire code base.
- XR0CSWV3h3kZWg 8y ago> we believe that the number of bugs is proportional to the number of lines of code Why would you believe that? And if you do believe that why don't you use a code golfing language?
- c0nfused 8y agoIts an interesting concept but, The choice of syntax seems bad. The definition bit looks like a function definition but behaves entirely differently. Why? Why not make it a constructor like everything else? People could look at it and be like "oh a match object" instead of wondering if you overloaded function. The selectors look like json, only assignable. Again make it obvious.I mean we could even just make it json why not.
- irrational 8y agoI made the same type of arguments about fat arrows but everyone told me to stop whining and I'd get used to it. Years later fat arrows still feel like a bad syntax choice.
- strainer 8y agoAnd they are ready to overload them here :/
- dvlsg 8y agoReally? I quite like them. I did get used to them in C# first, though. What would you have preferred?
- irrational 8y agoI would have preferred a word. const my_arrow_function = arrow_function(){} arrow_function my_arrow_function(){} arrow_function(){}
- warty 8y agoIn older C#, that would be delegate: delegate(int x){ return 10; } (But yeah, nowadays that would be:) (int x) => 10
- mattbierner 8y agoFrom a language design perspective, fat arrows make parsing unnecessarily complicated because you cannot distinguish "(a, b, c)" from "(a, b, c) => ..." without looking ahead or backtracking. Certainly not difficult to solve, but this choice makes extending arrow syntax more difficult and the fact that a production called `CoverParenthesizedExpressionAndArrowParameterList` exists in the language grammar is a pretty ugly IMO
- genezeta 8y agoLeaving aside syntax preferences or other superficial concerns, I find it discouraging that "Motivating Examples" for a proposal include direct references to particular libraries, or particular libraries' examples. I mean, that one (of two) motivations for adding a feature to a language is "Terser, more functional handling of Redux reducers", just feels wrong and casual.
- sharpercoder 8y agoThey should be included, as it simply is a valid use-case which most likely will actually be used. However, there should be many more examples or good real-world use-cases. Lack of those concerns me.
- karmajunkie 8y agoI think if you look at languages that support them natively, like F#, OCaml/Reason, or Elixir/Erlang, you'll find plenty of examples of real-world uses. Whether those would suffice to illustrate how to apply them in a JS codebase that has this proposal enabled, I cannot say. However, having gotten used to having them, I can safely say I'll always feel hobbled to work in a language that doesn't have them, so I'm very much in favor of adding them to JS, whether or not this is the proposal that wins out over time.
- timhwang21 8y agoStage zero proposals generally read less formally. IIRC they are held to lower standards and expected to be formalized in the later stages.
- austincheney 8y agoAbsolutely, agree. The code examples should be vanilla code, which could then be expanded to the preferences of any library/framework.
- curun1r 8y agoIt's probably more of a "know your audience" decision. Anyone who's used an ML-derived language will understand the motivation for pattern matching. But a large percentage of JS developers don't really have much background in non-mainstream languages or programming language theory, so they chose an example that's likely to resonate more with that group.
- sergiotapia 8y agoI wonder if they can make it behave like Elixir's pattern matching. Multiple functions with different params, same name.
- lightbyte 8y agoElixir's multiple function heads are just syntax sugar for a case statement.
- SilasX 8y agoIs that really the most pressing problem with Javascript? The lack of one more way of expressing a common pattern? Not, say, the lack of typing or ease of code obfuscation or unintuitive type comparisons the lack of a standard library or ...?
- devmunchies 8y agoare there any 10+ year old languages that are "advancing" as quickly as JS? Ruby? Python? C++? Why Not?
- mattbessey 8y agoI love where JS is heading, but perhaps its worth pointing out its a lot easier to rapidly advance a language that historically has been missing huge features.
- aylmao 8y agoI'd also argue none are as important as JS. People can choose to not use Ruby, Python or C++, but if you're doing web atm you're pretty much stuck with JavaScript.
- goatlover 8y agoYou mean are there any other languages trying to quickly catch up to C++'s complexity?
- pjmlp 8y agoAll professional languages reach C++'s complexity, which probably is not as complex as PL/I or Algol 68W were for their time. Python is my favourite example to pick up on this. Target at beginners and deemed as simple, yet I doubt anyone is able to know Python semantics since version 1.0 and by looking at a random codebase is able to state what is the minimum Python version required to run the code without errors. Also I very much doubt anyone knows Python's library cover to cover. Languages get complex because real world has complex needs. Even Go, the new poster child of simplicity, now has quite a few warts, because not everyone doing software like Google.
- goatlover 8y agoFair enough, and Python is a good example, but I'm guessing Scheme and Smalltalk managed to stay relatively simple over time, although I don't know how much of that would be chalked up to lack of mainstream support.
- ihsw2 8y agoFor those looking to digest more information on pattern matching in the JS world, there has been an open proposal for TypeScript to support pattern matching of some flavor. https://github.com/Microsoft/TypeScript/issues/165 https://github.com/Microsoft/TypeScript/issues/165
- lgessler 8y agoLooking at this as someone who's been writing a lot of ClojureScript lately, I'm reminded of how nice it is to be writing in a Lisp: if I felt this was the right syntactic construct for a common-enough problem in my codebase, I'd write a macro for it and get on with my life without having to wait for it to trickle through committees, compilers, and browser implementations.
- serpix 8y agosome-> (threading macro) and the fact that you can put an s-expression _anywhere_, these two language fundamental features alone put lisps way above c-style languages. You can laugh and continue sipping your espresso while reading the JS community bicker about syntax changes and what you are allowed to type.
- WaxProlix 8y agoAnd the next person to maintain your codebase would be grateful for your choice and insight, I'm sure. Permissiveness is good for small projects but it can feel like getting into a suit tailored specifically for everyone else as projects get bigger.
- lgessler 8y agoI did say if. Macros often aren't the right choice, but there are times when they're appropriate, and on the premise that the new syntax would be good and responsible, it's great to not have the headache of monitoring compatibility tables for 2+ years. When you get to the scale of enterprise software, though, I'd agree with you that the best thing to do is probably not to allow any macros at all. The inevitable abuse at the hands of inexperienced developers would quickly overtake any gains from more responsible macros without perhaps some clever and/or toilsome code review processes.
- jwr 8y agoI don't think this snarky remark is warranted. I think the point was that in Lisp-style languages (such as Clojure/ClojureScript) new features such as pattern matching can easily be added without "changing the language", as libraries. This is how core.async was added to Clojure, to pick a non-trivial example. Or more to the point, how core.match works. Additions such as those do not have to be one lonely programmer's macros, they can be libraries widely accepted by the community. I had a similar thought when reading the ECMAscript extension proposal: I'm glad that in the languages I use, features like that can be provided by libraries.
- Tloewald 8y agoSo the proposal is super confusing to me (but I hadn't seen match before). At first I thought it had something to do with regex. Essentially it's a switch variant that is (a) confusingly named 'match' (bad) (b) returns a value (good?) (c) and is actually a kind of function (wha?), since it (d) supports recursion, but (e) doesn't require break (good), (f) looks like a bag of inline functions but isn't (bad). How about provide a replacement for switch, with a name that isn't confusing that doesn't require break but otherwise has switch semantics, isn't recursive (we have a mechanism for that) and has the matching behavior suggested? Assuming we stick with 'match' it would look like: foo = match(x) { case {y: 1} : /* result if x.y === 1 */; ... } Seems far less confusing.
- sorenbs 8y agoTake a look at pattern matching in other languages like Scala. I find the proposed syntax strikes a great balance between being familiar (for people familiar with Scala etc) and using well understood js structures (destructoring) Would love for this to land :-)
- aylmao 8y agoLove this comment; reminds me of what I thought when I first encountered pattern matching. a. Yup, that's what it's called in OCaml, Scala, F#, etc. Might be a little confusing at first, but it's all about finding a "match" for your value, which is different from a guard in an "if" or a "switch". In an "if", you need to provide a boolean (or a value coercible to a boolean). In a "switch" you don't provide the boolean, but under the hood the switch is just iterating through and comparing your value to all cases: it computes the boolean for you by testing if two values are equal. Finding a "match" is different, because you're not comparing values, you're also comparing structure. So for example you can do things like match (v) { case { x, y: 3 } => ... case { y: 3, contents: { name: 'Foo', error }} => ... case { x, y } => ... } And it wont just compare "v" against all cases, do a deep comparison, check the existance of certain keys and bind variables as necessary so you can use them on `...`. b. More so than "returning a value" I like to think of it as "resolves to a value". Thinking of it as "returning" can be confusing since it might make it sound too much like a function. Switch/if are statements. They control flow, and ask the computer to do something. Another statement is assignment; `var a = 0;` "does" something, but it doesn't represent a value. Expressions like `3 + 2 + x`, `f(x)/2`, and `match({x:3}) {...}` represent a value that hasn't been computed, and then resolve to one. c. This is why I prefer to think of it as an expression: cause expressions resolve to values. Function calls are expressions too! d. If you're in a function, all expressions support recursion since you can mix them up. A e. Awesome. f. I think that's on purpose, because in a way each case acts a bit like a funciton. You can define "arguments" in it that get bound to values, and they resolve to another value.
- frou_dh 8y agoYou know that quip about C++ being an octopus made by nailing extra legs onto a dog? Is the same phenomenon somehow tasteful when it comes to ECMAScript {({..., sy: nt => ax, ...}({,})} ?
- GlennS 8y agoI feel like JavaScript is already a sort of functional language, so going in this direction is ok. It's the object/class additions where I think it's all going a bit C++. Start with prototypical inheritance, but with a Java-style `new` keyword that makes everything confusing. Next bolt on classes on the one hand, while correcting your prototype system `Object.create` on the other. R has 3 different object systems and none of them are any good. How long before JavaScript catches up?
- sjellis 8y agoI think that one of the reasons that classes were added to the language was that people kept implementing them anyway, so it was better to standardise. This may be a good thing: JavaScript arguably has to be multi-paradigm, more than other languages, because the user-base is so diverse.
- whatever_dude 8y agoI think C++ is the best example of where JS is heading. We have different ways of doing the same thing, and you have to know the "right" and "wrong" ways based on whatever was the latest proposal. We have fringe proposals that are just based on something cool some other language did, and they might stick or they might not. We'll soon have the really obscure constructs that nobody uses except for this guy on the 3rd floor, and he's really vocal about it so watch out. Maybe we'll even finally get macros in JavaScript [1] soon. 1: http://peter.michaux.ca/articles/macros-in-javascript-please http://peter.michaux.ca/articles/macros-in-javascript-please
- jiaweihli 8y agoI love pattern matching, but find libraries with sugar or unintuitive APIs hard to navigate. I built Rematch[1], which I hope avoids those two issues. [1] https://github.com/jiaweihli/rematch https://github.com/jiaweihli/rematch
- bterlson 8y agoI think it's good to note that this proposal is not far along the process. Pattern matching, if it clears TC39 (a tall order, to be honest), won't land in a spec for half a decade at least I would bet. So, keep the feedback coming, and don't worry that you'll have to learn this syntax tomorrow. It's still very early, and I wouldn't be surprised if there are at least a couple major revisions before anything like this lands in ECMAScript.
- gedy 8y agoWith babel plugins/transforms this could be used a lot sooner than that
- bterlson 8y agoBabel has a lot of plugins, and hopefully people don't have to learn all of them. How many people use stage-0 plugins for bind operator or do expressions? You're right that Babel (and TypeScript!) implement features earlier than they land in the spec, but at least TS does so only when it's almost for sure going to make it in (around stage 3) and people probably shouldn't be using stage 0-2 plugins for anything but experiments, IMO.
- abritinthebay 8y ago> if it clears TC39 (a tall order, to be honest), won't land in a spec for half a decade at least I would bet. Given current speed of iteration I think you can cut that in half. The key will be implementations - Babel plugins help with that.
- bterlson 8y agoThe current speed of iteration means you get updates in smaller batches rather than more throughput. Still important, but it's not like we're letting proposals bake less. Note how so far we've only gotten two big new features post-ES6 - async functions and async generators. Further, some features (e.g. decorators, bind operator) have had babel plugins for years and yet hasn't shipped in a spec.
- mattbierner 8y agoI would prefer `match { ... } (value)`, with the `match` keyword essentially creating a function that does the matching when it invoked. Minor seeming change, but then you can think of match as being a generalization of arrow functions instead of a special new language construct (i.e., `(...args) => ...` is just shorthand for `match { ...args => ... }`) I can understand why though they went with similar syntax to a switch statement though
- edflsafoiewq 8y agoThis wouldn't work if the match contained eg. break or return.
- mattbierner 8y agoYes, if match is an expression than this restriction is the correct design in my opinion
- abecedarius 8y agoThis might be too cute, but you could support both unambiguously: match (subject) { ... } and match { ... }.
- mattferderer 8y agoI would imagine you could do typeof === "string" or instanceof Foo to add JS's limited type support? Elixir is similar in that it's not a typed language but can allow limited types like this. I personally wish the syntax was similar to overloading functions in other languages, but I doubt that's possible due to the way destructuring & default values were implemented.
- bcheung 8y agoI'd like to see how this would handle nested matching in the examples.
- bcheung 8y agoI'm wondering whether types would be required to implement static analysis to see if a particular scenario in the match is not handled. Haskell has the ability to generate a compile error if you don't have a match specified for each possible permutation. This makes it easy to make sure you handle all possible inputs. This probably wouldn't be possible in JS. Probably the best that could be done would be if the default matcher was left off.
- emodendroket 8y agoThe example seems to be a dictionary, so of course you cannot guarantee that all possible permutations are covered.
- LOLCAT1024 8y agoThis proposal will increase code coupleing by fixing the object structure, this will lead to refactoring problems and so on. A better approach would allow to match objects by their fileds while leaving the structure of the object unspecified.
- edflsafoiewq 8y agoCan you elaborate? What do you mean "match objects by their fields"? How does the proposal not already do that?
- LOLCAT1024 8y agoMaybe I did not express my self correctly, what I meant was - in it's current state the proposal rquires, when matching against an object, to specify all it's fileds, say you have an object with keys a, b, c then even if you match soley against the values of a , b you are required to specify c and by doing so notify it's existence. This poses a problem , since if you now remove c or add a filed d then the match will break failing to the default case , this means failing silently the worst that can happen. The described situation will be more then common since objects are ubiquitous to modern day js. Sadly nobody noted the existence of such a design flaw , which in my opinion is rather big since the proposal in it's current state implicitly turns objects into some kind of types , which they are not, such transformation will result only in increased coe coupleing , since anyone who matches against an object basically specifies it's type and as a consequence only doom and despare will follow to anyone involved.
- edflsafoiewq 8y ago> in it's current state the proposal rquires, when matching against an object, to specify all it's fileds, say you have an object with keys a, b, c then even if you match soley against the values of a , b you are required to specify c and by doing so notify it's existence I think this is wrong. The proposal says that a pattern like `{x}` matches if the object supports `ToObject` and if its `x` property is not undefined. It doesn't say anything about requiring that the object have no other own-properties. This is consistent with how destructuring already works in JS (it ignores any extra properties).
- xodeus 8y agoIf I do the following: let visFilter = 'foo'; const newState = match (action) { {type: 'set-visibility-filter', filter: visFilter} => console.log(visFilter) } What happens? Is it checking if action.type === 'set-visibility-filter' && action.filter === 'foo' or is it destructuring the value of action.filter into visFilter?
- always_good 8y agoEvery example in on the readme demonstrates that using an identifier in that position becomes destructured assignment.
- xodeus 8y agofound the answer in the full proposal. Variables will always be assigned to, never checked for equality. To me this is pretty average and seems like it will cause magic numbers/strings/etc if I can't use constants where it makes sense. The proposed solution is to do something like { status: 200 } if (x === foo) => // do something which just seems (for this type of use case, maybe not all) like more boilerplate code for no real benefit over just doing something like if (res.status === 200 && res.x === foo) //do something I would much prefer if there was some sort of special operator used to either check equality or to destructure when matching so it is obvious what the code is doing.
- rattray 8y agoSurprised nobody has mentioned zkat's "fork", which contains a lot more detail: https://github.com/zkat/proposal-pattern-matching https://github.com/zkat/proposal-pattern-matching zkat (who is also an npm employee) is a leading committer to the tc39 version, so I think there's some chance that many aspects their version will be adopted into the proposal.
- techsin101 8y agoI just want to have ? Functionality in js like Ruby... So I can do let name = obj?.data[i]?.name; And not get error can't read property data of undefined, when there is something wrong, just have undefined as value. To fix this I've to write redudant checks for each level of nested property. Or do stuff like (obj || {}).prop....
- fauigerzigerk 8y agoThis reads very much like an ideology first, evidence second piece. How on earth is it bizarre to make neighborhood roads worse to drive on for commuter traffic? And defunding public transport? You can have a debate about these things, but calling it bizarre betrays the sort of "reasoning" that is dominated by an ideological anti public-anything bias.
- mgoetzke 8y agoare the `=>` actual hidden functions with own scope or are they syntactic sugar? If they are functions they wont have a name in stack traces and add overhead.