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

Proposition: supporting both options by making the Hack syntax a sugar syntax for unary functions

Open sharshuv-quotient opened this issue 3 years ago • 2 comments

Not sure if it was suggested already, but I think an easy way to make the unary-function vs Hack pipes proposition obsolete, is to make the "Hack" syntax into a separate feature. The idea is to treat any expression with the "%" as an unary function.

For example:

const fn = %.foo();
fn(x);

Will be interpreted as:

const fn = a => a.foo();
fn(x);

This is in my opinion a good feature regardless because arrow-unary functions (especially as callbacks) are very common and using this syntax can really make coding in those situations easier.

Also this makes the Hack syntax and the pipe in general too different features that can be discussed separately and implemented / not implemented separately, as both have value on there own.

sharshuv-quotient avatar Aug 29 '22 16:08 sharshuv-quotient

A similar idea was suggested in #276. The conversation within has some references to other conversations about it.

mAAdhaTTah avatar Aug 29 '22 17:08 mAAdhaTTah

In particular, note the arguments against this in the original Smart-Mix repo, which went to great effort to identify a useful subset of unary calling that could be mixed with topic expressions in a way that was easy to identify and difficult to get wrong.

Just doing a naive "if there's a topic token, do X, otherwise do Y" ends up having bad behavior for a couple of reasons, explained in the linked README.

tabatkins avatar Aug 29 '22 23:08 tabatkins

This is an interesting idea. It'd be really compelling even outside of the pipeline context if we had named function parameters and named placeholders.

let fn = %a + %b.foo();
fn(a:4, b:x)

(I wasn't able to find the discussion that tabatkins was referring to in the Smart-Mix readme.)

josephrocca avatar Dec 05 '22 08:12 josephrocca

Note that in @tabatkins response, it seems they have misunderstood the proposal made by OP.

This proposes adding a separate syntax for the definition of unary lambda functions using a topic token: %.foo defines topic => topic.foo.

And in combination with the F# pipeline operator that would approximate the Hack proposal: x |> %.foo -> x |> (topic => topic.foo) -> (topic => topic.foo)(x) -> x.foo.

So there is no "if the topic is there, do one thing, otherwise do another" like with the Smart-Mix proposal.

However, I do see other difficulties with the proposal. For example: [%.foo, %.bar]. Does that mean topic => [topic.foo, topic.bar], as it would with Hack? Or does it mean [topic => topic.foo, topic => topic.bar]? I'm not sure if a heuristic exists by which this question can be answered reliably and in a way that doesn't surprise developers.

Avaq avatar Dec 05 '22 12:12 Avaq

Ah, yes, I did misunderstand. Rather, this is essentially asking for Partial Function Application, just with an even wider syntax.

This is unworkable as a solution for the same reasons that F# + PFA is (it encourages the creation of a ton of one-shot functions, it doesn't work with await, yield, and other function-scoped abilities we add in the future, etc), but has the additional issue that the syntax is extremely ambiguous. PFA goes to some decent lengths to ensure that function-calling, by itself, is unambiguous; if you extend it to more operators it quickly runs into ambiguous situations, as you illustrated.

I'm going to go ahead and close this, then, as it's answered by https://github.com/tc39/proposal-pipeline-operator/issues/221

tabatkins avatar Dec 06 '22 00:12 tabatkins