10 ms·
A pipe operator for JavaScript: introduction and use cases
- wruza 5y agoPlease no. This “operator” turns everything into an unreadable mess. Where can one vote against it?
- slaymaker1907 5y agoUnreadable in your opinion. In my opinion, it is far more readable than the alternative in many cases.
- dataflow 5y agoA pipeline operator would be nice, but I just took a look and I agree that |> and % are difficult to read. I also think |> is hard to type, which makes it more painful. Admittedly I don't have a stellar solution to this though. Only alternative I can think of is ~
- deleted 5y ago[deleted]
- tentacleuno 5y agoThe tilde (~) operator is already used for Bitwise NOT[0]. [0]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_NOT https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- dataflow 5y agoThat's not an issue. This is a binary operator not a unary one.
- tentacleuno 5y agoIt is a unary operator, from my understanding of operators, as it only operators on one subject (~2). However, I very much doubt TC39 would use this character, as it would cause a great deal of confusion and poor semantics, not to mention the complexity on the engine side (does the user want NOT or pipe?)
- dataflow 5y agoNote we already use + as both binary and unary (and for both arithmetic and concatenation).
- mrblampo 5y agoExample case?
- slaymaker1907 5y agoStylistically I think it is most appropriate when you are writing conversions/cleanup/transformations. Places where method chaining is nice but not always possible. Suppose you are doing a bunch of string manipulation with custom string operations (maybe a custom regex engine with timeouts unlike the default JS regex API).
- joshschreuder 5y agoThere’s an example in the article. > const y = h(g(f(x))) This example of nested function calls needs to be read from the inside out (execution is f, g, then h) which is unintuitive to how we read and parse text. The alternative is to use intermediate variables instead of nested function calls to represent the control flow of f, g, h.
- bern4444 5y agoI've come to prefer storing each intermediate value in its own variable. Debugging becomes a lot easier this way with a break point available at each step of the process. There's nearly no disadvantage to creating the extra variables given how quickly they can be cleaned up by the GC in these cases.
- pacaro 5y agoHistorically I would have agreed with this position, but debuggers have gotten a lot better, so it's typically possible to break wherever you need to. The intermediate variables still have value, just not as much as they used to, and they do (arguably) increase the cognitive load for the reader
- colordrops 5y agoBut intermediate variables are almost always better if named properly, as they provide a contextual name as to the purpose of the output of the function. Then only very minor downside is a bit more typing and more lines of code.
- tylersmith 5y ago> Where can one vote against it? In repos you're contributing to.
- twistedpair 5y agoThe slippery slope toward Scala's operator madness. Please find a sensible stasis. Checkout this list of new JS/Node.js features [0] as an example. Will a world with the following be an improvement? [1] - ??= - ||= - &&= And don't forget the strife around the Python "walrus operator" := [2] [0] https://node.green/ https://node.green/ [1] https://github.com/tc39/proposal-logical-assignment/ https://github.com/tc39/proposal-logical-assignment/ [2] https://realpython.com/python-walrus-operator/ https://realpython.com/python-walrus-operator/
- valenterry 5y ago> The slippery slope toward Scala's operator madness. Or is Scala's way what languages eventually converge into? Funnily, in Scala, all of these are just simple plain methods. Including the pipe "operator". So Scala as a language is actually simpler here.
- dragonwriter 5y ago> Where can one vote against it? TC39, as the article notes, and where the F#-style pipe has been shot down enough that it's been abandoned in favor of the Hack-style one by those championing a pipe operator.
- userbinator 5y agoI am against this sort of churn, but for a different reason ---https://news.ycombinator.com/item?id=29894300 https://news.ycombinator.com/item?id=29894300
- edem 5y agoFor you maybe. For me it is a great addition. If you dont like it use font ligatures.
- epolanski 5y agoOne minor nitpick, there's no difference between n-ary functions and unary functions as any n-ary function is homomorphic to the curried version.
- drenvuk 5y agoThis is pretty disgusting to me. It just looks messy. const testPlus = () => { assert.equal(3+4, 7); } |> Object.assign(%, { name: 'Test the plus operator', }); The previous code is equivalent to: const testPlus = () => { assert.equal(3+4, 7); } Object.assign(testPlus, { name: 'Testing +', }); We could also have used the pipe operator like this: const testPlus = () => { assert.equal(3+4, 7); } |> (%.name = 'Test the plus operator', %) ; I don't really see the point in general purpose chaining. I don't really see the point of flatmapping tons of nested function calls. Instead we can abstract it and start another nested stack if necessary. I thought we moved away from utilizing promises towards async await because of the chaining issue. It feels like it's being repeated. The example from TC39 is also fairly insipid: console.log( chalk.dim( `$ ${Object.keys(envars) .map(envar => `${envar}=${envars[envar]}`) .join(' ') }`, 'node', args.join(' '))); I don't think it should have been written like that. The Object.keys().map().join() should've been assigned to an appropriately named variable before being used in another function. There are better ways to avoid writing code this way.
- CSSer 5y agoFrom earlier today: https://news.ycombinator.com/item?id=30124754 https://news.ycombinator.com/item?id=30124754
- user3939382 5y agoI like it. Anyone who’s written complex Excel formulas knows the pain of those deeply nested function calls. For those scenarios this is much easier to read IMHO.
- chana_masala 5y agoI like the analogy your comment has inspired: JS is the Excel of programming.
- jessaustin 5y agoI sort of thought Excel was the Excel of programming...
- dvt 5y agoWhat a syntactic mess. JS is slowly turning into C++. I've already complained about how spread[1] syntax breaks common intuition in certain use cases, I haven't even had time to keep up with all the insane operators they've been adding. [1] https://dvt.name/2018/06/02/spread-syntax-breaks-javascript/ https://dvt.name/2018/06/02/spread-syntax-breaks-javascript/ (excuse the code formatting, one of my plugins broke)
- apatheticonion 5y agoWASM can't get DOM access soon enough..
- udbhavs 5y agoIs it planned for the future? I can't find a link to any proposal or RFC
- apatheticonion 5y agoNo, they have been busy spending the last 4 years looking for a way to use Web Assembly to solve world hunger Really though it will come as a combination proposals - "interface types" being one of them
- minitech 5y agoPersonal opinion: none of the syntax or results in your blog post were confusing, other than square brackets looking confusingly like curly braces in the font. It’s how splat works in every language I’ve used. “This operation that doesn’t make sense doesn’t work” especially not confusing.
- dvt 5y agoRe-read that post and the idea that this is perfectly fine parenthesis redundancy: A = 'hello world' console.log( A ) // prints 'hello world' console.log( (A) ) // also prints 'hello world' But this breaks with a random-ass error because of how arrow functions interact with `...rest` parameters A = ['hello', 'world'] console.log( ...A ) // prints 'hello world' console.log( (...A) ) // SyntaxError: expected '=>' after argument list, got ')' Is still absolutely hilarious and reeks of "design by committee."
- forgotmyoldacc 5y agoAs someone who's used the pipe operator in a different language in a professional setting, I can attest that it makes code a lot easier to read and write.
- franciscop 5y agoThe problem with Javascript IMHO is that it's difficult to say "enough". As someone who uses it everyday and loves it, I believe it's in a decent place now, but it keeps adding more and more strange operators that virtually no one uses or has use for in everyday applications. Things like Symbols, BigInt, etc. are way too rare in JS and only useful under certain "ideas of workflows" to be worth being part of the core since they introduce a whole incompatible layer of dealing with things and don't mix well with the rest of the language. I'll even throw "classes" and "generators" to the list of things that were a mistake, as time has shown. This is the same with the pipe operator, we already have arrow functions, thenables, and TWO different types of .pipe(), which makes syntax a lot cleaner when needed. IMHO adding this pipe operator "|>" would be a mistake, it only complicates the language making: - Browser competition harder, when the language is really broad and difficult it makes it harder to create a new engine. - Mastering Javascript harder, there's a lot broader amount of concepts there which are not really useful except. - No real benefit as I explained. For some people's worldview it's better, but for us the rest of mortals[1] it's just overhead. A really good indicator of whether something is useful in core JS is: has someone made it into a library or sublanguage[2] that is widely used? Or a language feature? Promises and events def passes that test, while Symbols, classes, generators and this new pipe operator definitely don't. Bigint is arguable, since it passes the test but remains fairly fringe use-case in JS. [1] Note that I'm the first one to experiment with JS and try weird things! I'm just saying that these should remain broken experiments on my computer, or nice libraries in npm, but not part of the specification that no one uses. [2] Coffescript, JSX, Typescript, etc.
- brundolf 5y agoI think it's important to separate two major categories of recent JS additions: 1) Advanced features that cannot be replicated without runtime support 2) Syntax sugar Symbols, BigInt, and generators are the former. Pipes and classes are the latter. (1) gives library authors access to low-level primitives that can allow them to do things that were literally impossible before (I've gotten a lot of use out of Symbols, personally), but they aren't often used directly in application code. (2) are usually more application-facing, and may or may not be a big enough quality of life improvement to justify their existence. I guess what I'm saying is: just because you haven't seen lots of Symbols or generators in the wild doesn't mean they aren't having an impact, or weren't worth adding.
- brundolf 5y agoI think the base pipe operator by itself is nothing but a win; I think it's pretty clear and unambiguous even if you aren't familiar with it, and it makes certain cases much more elegant. I don't really see any downsides to it, except maybe that it has limited usefulness on its own. My feelings about the "Hack pipe operator" are much more complicated. I can see how it dramatically expands the usecases for piping as a whole, given JavaScript's other norms and constraints (no automatic currying, lots of method calls). But I also think it tangles up control-flow in weird ways that could get really hairy fast. And at some point, when you're no longer "just piping" into a unary function, are you really gaining much benefit over the normal function call syntax?
- syspec 5y agoI know pipe is popular in other languages and on Linux, but all of the examples on that page look contrived, and seem more like a justification after the fact. If I had to pick, I'd choose the more limited F# style, it's easier to understand and imposes some sane constraints around usage. No more JS code golf, brevity in itself should be a non-goal
- _nub3 5y agoInstead of adding more features to a basically broken language, why not fixing the essentials first? typeof null === "object" language consstency etc but hey, let's add more syntax sugar
- zkldi 5y agoBackwards Compatibility -- So much code out there depends that typeof null === "object".
- egeozcan 5y agoDuplicate of recent discussion: https://news.ycombinator.com/item?id=30124754 https://news.ycombinator.com/item?id=30124754
- edave64 5y agoThis feels like a massive break with the most fundamental syntax of the language. The examples might look more readable in isolation, but I feel this would reduce readabilty in practice by making the language more complex to read and for allowing massively mononolithic expressions, like the ternary operator.