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

Alternate syntax with names #15

Closed jamiebuilds closed 7 years ago

jamiebuilds commented 7 years ago

Without partial application, using the pipeline operator, you need to create extra functions, which is bad. But there's an argument to be made that having names for the parameters is good.

let result = tokenize(code, tokenizeOpts)
  |> tokens => parse(tokens, parseOpts)
  |> ast => transform(ast, transformOpts)
  |> transformed => generate(transformed, generateOpts);

This proposal gets rid of the extra functions, but it's also gets rid of the names which is not the primary goal.

let result = tokenize(code, tokenizeOpts)
  |> parse(?, parseOpts)
  |> transform(?, transformOpts)
  |> generate(?, generateOpts);

What if we used an alternate syntax (or extended the proposed syntax) to require (or allow) names for the placeholders:

let result = tokenize(code, tokenizeOpts)
  |> parse(?tokens, parseOpts)
  |> transform(?ast, transformOpts)
  |> generate(?transformed, generateOpts);
let maxGreaterThanZero = Math.max(0, ...?values);

maxGreaterThanZero(1, 2); // 2
maxGreaterThanZero(-1, -2); // 0

I personally think that this is easier to read, but more importantly there is value for tooling.

Example: DevTools

If you want to create a conditional breakpoint, it would be useful to have a name to go off of.

Break when: `Array.isArray(ast)`

Example: Type Checkers

Placeholder "?ast" was expecting an Object, but it received an Array.
rbuckton commented 7 years ago

I don't feel specifying names here makes sense, as they would be unobservable if partial application uses eager evaluation (which is the current consensus view). Also, you would not be able to set a breakpoint that could be hit inside of the partially applied function call.

Type checkers would not have this issue, as they can determine the resulting signature of the partial function and use the argument names of the original function. I've already experimented with this in TypeScript and its fairly trivial.