8 ms·
Not only have we been waiting for 10 years, the most likely candidate to go forward is not at all what we wanted when the proposal was created: We wanted a pip
by avaq 1y ago
Not only have we been waiting for 10 years, the most likely candidate to go forward is not at all what we wanted when the proposal was created:
We wanted a pipe operator that would pair well with unary functions (like those created by partial function application, which could get its own syntax), but that got rejected on the premise that it would lead to a programming style that utilizes too many closures[0], and which could divide the ecosystem[1].
Yet somehow PHP was not limited by these hypotheticals, and simply gave people the feature they wanted, in exactly the form it makes most sense in.
[0]: https://github.com/tc39/proposal-pipeline-operator/issues/221#issue-999806278 https://github.com/tc39/proposal-pipeline-operator/issues/22...
[1]: https://github.com/tc39/proposal-pipeline-operator/issues/233#issuecomment-928217657 https://github.com/tc39/proposal-pipeline-operator/issues/23...
- xixixao 1y agoI guess partially my fault, but even in the article, you can see how the Hack syntax is much nicer to work with than the functional one. Another angle is “how much rewriting does a change require”, in this case, what if I want to add another argument to the rhs function call. (I obv. don’t consider currying and point-free style a good solution)
- lexicality 1y agoAm I correct in my understanding that you're saying that the developers of the most widely used JS engine saying "hey we can't see a way to implement this without tanking performance" is a silly hypothetical that should be ignored?
- avaq 1y agoThey can't implement function application without tanking performance? I find that hard to believe. Especially considering that function application is already a commonly used (and, dare I say: essential) feature in the language, eg: `Math.sqrt(2)`. All we're asking for is the ability to rewrite that as `2 |> Math.sqrt`. What they're afraid of, my understanding goes, is that people hypothetically, may start leaning more on closures, which themselves perform worse than classes. However I'm of the opinion that the engine implementors shouldn't really concern themselves to that extent with how people write their code. People can always write slow code, and that's their own responsibility. So I don't know about "silly", but I don't agree with it. Unless I misunderstood and somehow doing function application a little different is actually a really hard problem. Who knows.
- nilslindemann 1y agoYour simple example (`2 |> Math.sqrt`) looks great, but when the code gets more complex, then the advantage of the pipe syntax is less obvious. For example, foo(1, bar(2, baz(3)), 3) becomes something like 1 (2, (3 |> baz) > bar), 3 |> foo or (3 |> baz) |> (2, % |> bar) |> (1, %, 3 |> foo) That looks like just another way to write a thing in JavaScript, and it is not easier to read. What is the advantage?
- avaq 1y agoUhm, don't do it, then. That's like arguing that the addition of the ternary operator is a bad one because not all if/else blocks look better when translated into it. The goal is to linearlize unary function application, not to make all code look better.
- sir_eliah 1y agoI think the commenter meant that once the new syntax is approved and adopted by the community, you have no choice to not use the syntax. You'll eventually change your project and will be forced to deal with reviewing this code.
- dotancohen 1y ago_You_ might not use it, but somebody's going to send a PR, or some LLM is going to spit it out, or some previous maintainer put it in there, or will be in some tutorial, or it will be in some API documentation. You are going to have to deal with it as a mess at some point. One of the downfalls of perl was the myriad of ways of doing any particular thing. We would laugh that perl was a write only language - nobody knew all the little syntax tricks.
- jeroenhd 1y agoWith JS' async/await system basically running on creating temporary closures, I don't think things will change all that much to be honest. Furthermore, I don't see why engines should police what is or isn't acceptable performance. Using functional interfaces (map/forEach/etc.) is slower than using for loops in most cases, but that didn't stop them from implementing those interfaces either. I don't think there's that much of a performance impact when comparing const x = fun1(abc); const y = fun2(x); const z = fun3(y); fun4(z); and abc |> fun1 |> fun2 |> fun3 |> fun4 especially when you end up writing code like fun1(abc).then( (x) => fun2(x)).then( (y) => fun3(y)).then((z) => fun4(z)) when using existing language features.
- ufo 1y agoThe problem they were discussion in the linked Github issue are pipelines where the functions receive more than one argument. const x = fun1(a, 10) const y = fun2(x, 20) const z = fun3(y, 30) In this case the pipeline version would create a bunch of throwaway closures. a |> ((a) => fun1(a, 10)) |> ((x) => fun2(x, 20)) |> ((y) => fun3(y, 30))
- hajile 1y agoClosures won over OOP in Javascript a long time ago (eg, React switching from classes to functions + closures), but they still keep trying to force garbage like private variables on the community. Loads of features have been added to JS that have worse performance or theoretically enable worse performance, but that never stopped them before. Some concrete (not-exhaustive) examples: * Private variables are generally 30-50% slower than non-private variables (and also break proxies). * let/const are a few percent slower than var. * Generators are slower than loops. * Iterators are often slower due to generating garbage for return values. * Rest/spread operators hide that you're allocating new arrays and objects. * Proxies cause insane slowdowns of your code. * Allowing sub-classing of builtins makes everything slow. * BigInt as designs is almost always slower than the engine's inferred 31-bit integers. Meanwhile, Google and Mozilla refuse to implement proper tail calls even though they would INCREASE performance for a lot of code. They killed their SIMD projects (despite having them already implemented) which also reduced performance for the most performance-sensitive applications. It seems obvious that performance is a non-issue when it's something they want to add and an easy excuse when it's something they don't want to add.
- tracker1 1y agoI wish I could upvote this more than once. I really liked the F# inspired pipe operator proposal and even used it a bit when I used to lean on 6to4/babel more, but it just sat and languished forever it seems. I can't really think of any other language feature I've seen since that I would have wanted more. The new Temporal being one exception.
- hajile 1y agoIt seems like none of the really good language proposals have much traction. Proper Tail Calls have been in the language for TEN YEARS now, but v8 and Spidermonkey still violate the spec and refuse to implement for no good reason. Record/tuple was killed off despite being the best proposed answer for eliminating hidden class mutation, providing deep O(1) comparisons, and making webworkers/threads/actors worth using because data transfer wouldn't be a bottleneck. Pattern matching, do expressions, for/while/if/else expressions, binary AST, and others have languished for years without the spec committee seemingly caring that these would have real, tangible upsides for devs and/or users without adding much complexity to the JIT. I'm convinced that most of the committee is completely divorced from the people who actually use JS day-to-day.
- nobleach 1y agoI know that was the reasoning for the Records/Tuples proposal being shot down. I haven't dug too deeply into the pipeline operators other than to get a feel for both proposals. Most of the more interesting proposals tend to languish these days. When you look at everything that's advanced to Stage 3-4, it's like. "ok, I'm certain this has some amazing perf bump for some feature I don't even use... but do I really care?"
- WorldMaker 1y agoI am wondering if PHP explicitly rejecting Hack-style pipes (especially given the close ties between PHP and Hack, and that PHP doesn't have partial application, but JS does, sort of, though its UX could be improved) will add leverage to the F#-style proposal over the Hack-style. It may be useful data that the TC-29 proposal champions can use to fight for the F# style.