This proposal introduces a new syntax using the #
, ?
(any number of ?s after each other), ?x
(x ∈ ℕ), ?r
tokens which allow you to partially apply an expression by acting as placeholders for a value or values.
Any and all feedback and ideas are greatly appreciated. Use the issues to post questions/ideas and send pull requests for any content updates. Fixes, clarifications, and especially usage examples are definitely helpful.
For more information see the TC39 proposal process.
- Halasi Tamás (@trustedtomato)
[1,2,3,4,5,6,7,8,9].map(#1+?); // partially apply an operator
//=> [2,3,4,5,6,7,8,9,10]
[1,2,3,4,5,6,7,8,9].reduce(#?+?); // use an operator as a function
//=> 45
['cat', 'coconut', 'carrot', 'dog', 'sun'].filter(#?.startsWith('c')); // partially apply a function/method
//=> ['cat', 'coconut', 'carrot']
The #
operator (precedence: 3.5) makes the affected expression a function. All upcoming tokens are only interpreted in this expression.
The ?
is a variable which will have the value of the corresponding argument. The first one stands for the first argument, the second for the second, etc. The order is determined by the order of their appearance in the code.
const add = #?+?;
// const add = (x,y) => x+y;
const addOne = #1+?;
// const addOne = (x) => 1+x;
The number specifies the ordinal position of the parameter. They allow the usage of an argument more than once & swap their order. Numbering starts from 0. The unnumbered ?
s fill out the left out parameters from left to right.
const power = #?0**?1;
// const power = (x,y) => x**y;
const basicTetration = #?0**?0;
// const basicTetration = x => x**x;
const flippedPower = #?1**?0;
// const flippedPower = (x,y) => y**x;
const foo = #bar(?1,?2,?,?1,?,?4,...?r,?);
// const foo = (x0,x1,x2,x3,x4,x5,...xs) => bar(x1,x2,x0,x1,x3,x4,...xs,x5);
The ?r
is an array of the arguments after the last used parameter.
const maxWithTheMinOf0 = #Math.max(0, ?, ...?r, ?);
// const maxWithTheMinOf0 = (x,y,...zs) => Math.max(x,...zs,y)
const foo = #Math.max(0, ?, ...?r, ?2);
// const maxWithTheMinOf0 = (x,_,y,...zs) => Math.max(x,...zs,y)
Conditional expressions:
The ?
token is used in conditional expressions, but its not ambigous, because in this proposal, a ?
cannot follow an expression, while in a conditional expression it always does. (e.g. in f(a?
the ?
is definitely a conditional operator while in f(?
it's definitely a placeholder).
Optional chaining:
The operator ?.
must appear directly after an expression, while the ?
variable can't.
The following is a high-level list of tasks to progress through each stage of the TC39 proposal process:
- Identified a "champion" who will advance the addition.
- Prose outlining the problem or need and the general shape of a solution.
- Illustrative examples of usage.
-
High-level API(proposal does not introduce an API).
- Initial specification text.
- Optional. Transpiler support.
- Complete specification text.
- Designated reviewers have signed off on the current spec text.
- The ECMAScript editor has signed off on the current spec text.
- Test262 acceptance tests have been written for mainline usage scenarios and merged.
- Two compatible implementations which pass the acceptance tests: [1], [2].
- A pull request has been sent to tc39/ecma262 with the integrated spec text.
- The ECMAScript editor has signed off on the pull request.
It would play nicely with the pipeline operator.
Or you might be interested in other partial application proposals:
- a
.papp
method for functions: gilbert/es-papp - a proposal very similar to this, but just for functions: rbuckton/proposal-partial-application