tc39 / proposal-partial-application

Proposal to add partial application to ECMAScript
https://tc39.es/proposal-partial-application/
BSD 3-Clause "New" or "Revised" License
1.02k stars 25 forks source link

Idea: Restrict and merge with pipeline proposal? #12

Closed gilbert closed 5 years ago

gilbert commented 7 years ago

Take the following two examples:

// Valid
arg
  |> f
  |> g(10, ?)

// Idea: Make this a syntax error
var h = g(10, ?)

A lot of discussion and debate centers around the semantics of the second example. However, in the first form there is no ambiguity argument to be had; |> invokes immediately, making the "bind by name" vs "bind by value" debate moot.

If restricted in this manner, it could also be merged into the pipeline operator proposal, allowing us to reap its benefits probably sooner than later.

Thoughts?

jridgewell commented 7 years ago

I don't think restricting it to pipeline fixes the ambiguity:


let i = 10;
function updateI() {
  i++;
}

arg
  |> updateI
  |> g(i, ?);
gilbert commented 7 years ago

According to the currently proposed spec, the left argument to |> is evaluated before the right, so I believe g would unambiguously be called with 11 in your example.

rbuckton commented 7 years ago

I don't think restricting it to pipeline fixes the ambiguity:

I wouldn't necessarily say this is ambiguous, but not yet defined. I haven't picked a specific direction (eager evaluation or deferred evaluation) in stage-0 as I want to discuss this with the committee. Once we have chosen a direction then the exact semantics will be documented, making the behavior unambiguous.

I believe this proposal has significant value as a stand-alone feature, with or without pipeline (though they definitely dovetail with each other).

gilbert commented 7 years ago

You're right, it's not ambiguous; I think "argument" is a more accurate word. I will update my post.

jridgewell commented 7 years ago

Wow, I'm not sure what I was thinking. 😳

gilbert commented 7 years ago

@rbuckton Responding to your second paragraph: I completely agree it has value, but I'm just concerned about timing. I would rather have a restricted version of this proposal land at the same time as pipeline op, than for pipeline op to land first and this one later.

Another way to think about it: the restricted version is simpler, and bundling with the pipeline op might be able to get it through the four stages faster. At the same time, a standalone partial app can exist alongside.

But who knows, maybe tc39 will like both proposals at the same time, and not be put off by this proposal's current semantic debate. I'm not sure; my suggestion is more of a process optimization than anything else.

rbuckton commented 7 years ago

If we restrict this proposal to only use within pipeline, we could be blocking future adoption of other parts of this proposal in light of #13, unless we also adopt #13 in the combined proposal:

const result = x
  |> ^addOne(?)
  |> ^double(?);

If we don't adopt ^ (or some other token) in a combined proposal, then the semantics would be confusing if we did adopt ^ for full partial application. For example:

// partial app, ^ marker
^f(); // () => f()
^f(?); // y => f(y);

// pipeline, no ^ marker
x |> f(); // f()(x)
x |> f(?); // (y => f(y))(x)

// pipeline, mixed with partial app with ^ marker
x |> ^f(); // (() => f())(x)
x |> ^f(?); // ((y) => f(y))(x)

If pipeline supports ? and we later add partial app using ^, it would be easy to get the two confused with undesirable results. As a result, we either need to keep the proposals separate, or abandon partial application entirely except when used with pipeline.

rbuckton commented 5 years ago

I am closing this issue as I strongly believe that partial application is valuable for Functional Programming outside of the pipeline use case. Additional rationale for how this proposal relates to the various pipeline proposals can be found in the explainer.