Hacker News new | ask | show | jobs
by mg 994 days ago
This would be my preferred syntax:

    status = greeting+"!" ~> capitalize ~> send
This would need 2 changes to JS:

1: ~> being a pipe operator

2: Calling an async function from within an async function implies await

Without 2, it would look like this:

    status = greeting+"!" ~> capitalize ~> await send
2 comments

There is a proposal to add the pipeline operator |> to the standard that works similar to what you have here.

https://github.com/tc39/proposal-pipeline-operator

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 feels a bit unnatural to pipe multiple arguments like that in JS, and you could inline them in the first call without losing legibility:

    a = c(b, 7) |> d(%)
It's the arguments added way down the line that are problematic:

    a = f((e(d(c(b))), 4), 5)
    a = ((b ~> c ~> d), 4 ~> e), 5 ~> f
    a = b |> c(%) |> d(%) |> e(%, 4) |> f(%, 5)
Smart pipes [1] were a bit nicer about that:

    a = b |> c |> d |> e(#, 4) |> f(#, 5)
Basically you would use # token whenever you wanted an expression and just a function name when you needed to pass a single argument. Best of both worlds IMO.

Perhaps it could even be extended for Curry-ish function syntax (although it isn't as obvious):

    a = b |> c(7) |> d
    a = d(c(7, b))
Too bad it was withdrawn.

[1]: https://github.com/tc39/proposal-smart-pipelines

P. S. When studying Haskell on a CS course in school, I used to define exactly the same squiggly arrow operator for my programs :-)

    x ~> f = f x
> P. S. When studying Haskell on a CS course in school, I used to define exactly the same squiggly arrow operator for my programs :-)

Haskell base already has the reverse application operator (&) which does the same thing. Not included in the prelude but can be imported from Data.Function. [1] It's defined as:

  (&) :: a -> (a -> b) -> b
  x & f = f x
Not that there's anything wrong with using your own definitions, just thought I'd point it out!

[1] https://hackage.haskell.org/package/base-4.18.1.0/docs/Data-...

This:

    a = f((e(d(c(b))), 4), 5)
Seems not to make sense. Replacing c(b) with x we get:

    a = f((e(d(x)), 4), 5)
Replacing d(x) with x we get:

    a = f((e(x), 4), 5)
Replacing e(x) with x we get:

    a = f((x, 4), 5)
What is that?
Sorry, messed up parens here. It should have been:

    a = f(e(d(c(b))), 4), 5)
b is passed to c, then the result is passed to d, then to e along with 4 as a second parameter, and finally to f along with 5.

    a = f(e(d(c(b))), 4), 5)
That has 4 opening parenthesis and 5 closing parenthesis.

    b is passed to c

        b ~> c

    then the result is passed to d

        b ~> c ~> d

    then to e along with 4 as a second parameter

        b ~> c ~> d,4 ~> e

    and finally to f along with 5

        b ~> c ~> d,4 ~> e,5 ~> f
Aside, but there's another kind of syntax possible here:

    const result = (
      await fetch(url)
        .json()
        ::Object.keys
        .map(key => ...)
        ::new ByteArray
    );
Does JS have a splat operator? So:

  a = (b, 7) |> c(*%) |> d(%)
Too much operator soup I guess.
Yeah, it is the ellipsis:

  a = b |> c(...%, 7) |> d(%)
Spaciousness helps here a bit, but still way too many syntax, I agree.
It took me a moment, but your version is very nice.