Live data from Hacker News

Show HN: A JavaScript function that looks and behaves like a pipe operator

github.com

41–50 of 148 posts

Re: Show HN: A JavaScript function that looks and behaves like a pipe operator

#41
post #24

I use ppipe: https://github.com/egeozcan/ppipe Looks tidier to my eyes const newPipe = ppipe.extend({ divide (x, y) { return x / y; }, log(...params) { console.log(...params); return params[params.length - 1]; } }); const res = await newPipe(10) .pipe(x => x + 1) .divide(_, 11) .log("here is our x: ") //logs "here is our x: 1" .pipe(x => x + 1) // 2

But then you have to define each method in advance, it doesn’t look like the pipeline operator at all, but more like the old jQuery.fn.method shenanigans.

Re: Show HN: A JavaScript function that looks and behaves like a pipe operator

#42
post #5

Its all a problem of formatting, for me this is simple to read. const { status } = await send( capitalize(greeting) + "!" ) But i would not concat things in a method call, bad style. const message = capitalize(greeting) + "!" const { status } = await send(message) The example from the page is a little bit too simple. With complex operations a pipe-method would make more sense. But i will wait for the native pipeline-…

I think the use of template strings simplifies it, even inline: const { status } = await send(`${capitalize(greeting)}!`) console.log(status) It does reduce the number of discrete operations to make the pipe example look more impressive, though.

But you have to look at the whole string and check if send has a further parameter. With `send(msg)` you see it without taking extra time of reading.

And let the compiler optimize your code, that is the job of a compiler. Write your code for humans.

Re: Show HN: A JavaScript function that looks and behaves like a pipe operator

#43

The following example code is a bit hard to read: const { status } = await send(capitalize(greeting) + "!") console.log(status) I disagree, I find this example code very easy to read because it reads like idiomatic Javascript. Unlike this library.

Yeah, it's concerning when even the contrived first example is less clear in the 'solution' than it is in the alleged problem.

Re: Show HN: A JavaScript function that looks and behaves like a pipe operator

#44
Lisper screaming

See Clojure macros for thread-first `->`, thread-last `->>`, thread-as `as->`, `some->`, `some->>` and `cond->`: https://clojure.org/guides/threading_macros

You can leave all this hurt behind you and use ClojureScript, which compiles to JavaScript.

Re: Show HN: A JavaScript function that looks and behaves like a pipe operator

#45
post #33

Earlier quoted context omitted.

Right - because this library tries to fake a new language syntax feature without the actual support for it, it ends up being the worst of both worlds. Even ignoring the lines-of-code explosion, the non-standard use of parens/spacing makes it incredible difficult for me to parse. Props to the author for trying out something neat, but this is probably a bit to clever for my liking.

> the non-standard use of parens/spacing makes it incredible difficult for me to parse. Same here. Not to mention this wouldn't work in a codebase with an autoformatter.The idea/API is clever. So, a pretty cool experiment I suppose

Author here. Thanks for your nice comment. I added a note to say it does work with autoformatters too. Actually someone in a comment below said he or she prefers the autoformatted syntax.

Re: Show HN: A JavaScript function that looks and behaves like a pipe operator

#46
post #28
post #20

Earlier quoted context omitted.

Nowadays, as someone writing a library, you can work around prototype pollution via Symbols and let your users modify prototypes on their terms.

Would that mean that instead of obj.pipeTo() I'd have to call obj[PIPE_TO] or something like that?

Essentially. And then have:

  Object.prototype.pipeTo = Object.prototype[PIPE_TO]
or some other name instead of `pipeTo` should there be a conflict.

JS already has a few well-known symbols like Symbol.toPrimitive that allow one to modify an object's behaviour (in this case what happens when `valueOf` or `toString` is called), so there's precedent.

Re: Show HN: A JavaScript function that looks and behaves like a pipe operator

#47
post #9

I had a hard time reading the example until I applied the "normal" JS indentation, that would also likely be applied by Prettier and the likes. V(greeting, // initial value "hi" V(capitalize), // custom function call "Hi" V.concat("!"), // String method `concat` call "Hi!" V(send), // custom async function call Promise { } V.status, // automatic promise chaining + getting property Promise { 200 } V(console.log), // a…

Author here. Thanks for your nice comment. I added a note to show the "normal" autoformatted syntax.

Re: Show HN: A JavaScript function that looks and behaves like a pipe operator

#48
post #22

Earlier quoted context omitted.

Which is basically what the proposal is https://github.com/tc39/proposal-pipeline-operator#this-prop...

The difference is that they want to turn a = d(c(b,7)) into a = b |> c(%,7) |> d(%) and I would like to see it turn into a = b,7 ~> c ~> d

It took me a moment, but your version is very nice.

Re: Show HN: A JavaScript function that looks and behaves like a pipe operator

#49
The "vertical" example looks contrived in JavaScript, but if that's your thing, I think it's OK.

But please don't promote antipatterns from languages that actually have a pipe operator (like Elixir) such as the '''concat("!")''' where the previous implementation's version using an operator is much clearer and more idiomatic.

I see a ton of Elixir code where people shoe-horn things into a vertical pipeline where the "normal" code would be a lot more readable, for example invoking '''Kernel.+(2)''' instead of just doing '''my_var + 2'''

Re: Show HN: A JavaScript function that looks and behaves like a pipe operator

#50

Just like Clojure's threading operator. (-> x (f) (g) (h)) https://clojure.org/guides/threading_macros

For those that don't know. In Clojure it is also perfectly valid to drop the parantheses for each subsequent call in a threading macro if you don't want to pass in any additional arguments:

  (-> x f g h)
If you need to pass an additional argument to g you can always do:

  (-> x f (g foo) h)
There are thread first ->, thread last ->>, and even a thread as "as->" depending on where you want to place the argument when you pipe the result through the thread of functions.
Post reply on HN