proposal-pipeline-operator icon indicating copy to clipboard operation
proposal-pipeline-operator copied to clipboard

Combining `|>` with `=>`

Open getify opened this issue 3 years ago • 2 comments

I have a request/proposal to consider. I recognize it would almost certainly be made into its own proposal, but since it's deeply related to |> I wanted to raise it here first.

The |> operator is like an IIFE in that it immediately evaluates. I anticipate that a lot of people will want to use this operator for function composition -- see all the debate over Hack vs F# -- and in the FP world, composition is often about setting up a function to be used, later and/or multiple times.

A natural adaptation then is to wrap a |> pipeline expression into an => arrow function. So, for example:

const formatOrder = record => extractOrderDetails(record) |> addCustomerInfo(^) |> renderOrder(^);

// or more generally:

const formatOrder = record => record |> extractOrderDetails(^) |> addCustomerInfo(^) |> renderOrder(^);

In FP terms, the repetition of record as a named parameter, and then listing it again in the first expression of the pipeline, is non-point-free. Generally there's a preference towards point-free where practical.

Since I anticipate a fair amount of such function wrappers around pipeline expressions, from FP-inclined developers, it would be nice if we could have a specialized arrow-function form for such pipelines, eliminating the repetition of the parameter name, in a point-free style.

What I am requesting/proposing is, a |=> form for arrow functions. It would define an arrow function whose body is automatically a pipeline expression. Additionally, it would automatically assign the first parameter to the topic of the pipeline's first expression. Thus, the above could be done this way:

const formatOrder = record |=> extractOrderDetails(^) |> addCustomerInfo(^) |> renderOrder(^);

I anticipate most everything else about => would be the same for the |=> form, including the ability to actually do any number of parameters (only the first one being bound to the topic), etc. Perhaps one difference might be |=> would only need the concise body form.

getify avatar Aug 21 '22 15:08 getify

There’s a similar idea that is already discussed in the explainer: pipe functions that would use a prefix +> operator (where +> is a symbol “between” => and |>).

Your example function:

record |=> extractOrderDetails(^^) |> addCustomerInfo(^^) |> renderOrder(^^)

…would be:

+> extractOrderDetails(^^) |> addCustomerInfo(^^) |> renderOrder(^^)

Other examples from the explainer:

a.map(+> f(^^, 0))
a.map(+> ^^ + 1)
a.map(+> f(^^, 0) |> g(1, ^^))
a.map(+> f(^^, ^^))
a.sort(+> f(^^0, ^^1))

Although I have not formally proposed pipe functions, when I did present them as an idea, they haven’t received much enthusiasm from the Committee outside of myself, since x => x |> … doesn’t seem to be considered a huge annoyance that deserves heavy new syntax.

js-choi avatar Aug 21 '22 18:08 js-choi

I hadn't seen the +> part of the proposal explainer... thanks for pointing it out.

I guess my reaction is, those are a much heavier syntax addition (with more power/flexibility), so perhaps my simplified |=> could be considered as an optional compromise in the mix if +> and the ^^3 stuff is seen by the committee as too much.

getify avatar Aug 21 '22 18:08 getify