Function partial application, operator partial application and all that fun stuff.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

Partial Expression Syntax for ECMAScript

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.


Stage: #1
Champion: #1

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.


Some examples which regularly come up

[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'] 


# and ?

The # operator (precedence: 4.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 ?r is an array of the arguments which were not symbolized by any ?.

const maxWithTheMinOf0 = #Math.max(0, ?, ...?r, ?);
// const maxWithTheMinOf0 = (x,y,...zs) => Math.max(x,...zs,y)

?x (?0, ?1, ?2)

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);


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. f(a? is definitely a conditional while f(? is definitely a placeholder).

Optional chaining:
The operator ?. must appear directly after an expression, while the ? variable/parameter can't.


The following is a high-level list of tasks to progress through each stage of the TC39 proposal process:

Stage 1 Entrance Criteria

  • 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).

Stage 2 Entrance Criteria

Stage 3 Entrance Criteria

Stage 4 Entrance Criteria

  • 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.

Related proposals

It would plays nicely with the pipeline operator.
Or you might be interested in other partial application proposals: