Pleasant Notation for promise pipelining.
- Mark S. Miller @erights, Agoric
- Michael Fig @michaelfig, Agoric
- Chip Morningstar @FUDCo, Evernote
Presented to TC39 (Javascript standards committee), achieving stage 1.
This is a follow on proposal to proposal-eventual-send, providing syntactic sugar for the APIs of that proposal.
The 2011 ECMAScript strawman concurrency proposal also described a simple desugaring of an infix bang (!) operator to support promise pipelining. To avoid conflict with TypeScript, this proposal instead introduces the wavy dot (~.) syntax.
Like the (?.) of the optional chaining proposal, wavy dot (~.) is a proposed infix operator with the same precedence as dot (.). Both can be understood as adjective dot, i.e., an operation that is dot-like, but differs according to the adjective. Once the optional chaining proposal is accepted, we will add to this proposal an operator combining the two adjectives, such as (?~.) or (~?.).
When the wavy dot expression occurs in a syntactic context in which the value of the expression might be used, the syntax has the following equivalences
Syntax | Internal Method |
---|---|
p~.name |
p.[[GetSend]]('name') |
p~.[prop] |
p.[[GetSend]](prop) |
p~.(...args) |
p.[[ApplyFunctionSend]](args) |
p~.name(...args) |
p.[[ApplyMethodSend]]('name', args) |
p~.[prop](...args) |
p.[[ApplyMethodSend]](prop, args) |
When the expression occurs in a syntactic context where the value of the expression is obviously ignored, such as an ExpressionStatement, the equivalences are as above, but using the [[*SendOnly]] variant of these internal methods.
Syntax | Internal Method |
---|---|
void p~.(...args); |
p.[[ApplyFunctionSendOnly]](args) |
void p~.name(...args); |
p.[[ApplyMethodSendOnly]]('name', args) |
void p~.[prop](...args); |
p.[[ApplyMethodSendOnly]](prop, args) |
Abstract Syntax:
Expression : ...
Expression ~. [ Expression ] // eventual get
Expression ~. Arguments // eventual apply function
Expression ~. [ Expression ] Arguments // eventual apply method
Attempted Concrete Syntax, where "..." signifies the existing productions of that non-terminal. Our intention is that this syntax follow the pattern of the optional chaining proposal.
WavyDot ::
~. [lookahead ∉ DecimalDigit]
MemberExpression : ...
MemberExpression WavyDot [ Expression ]
MemberExpression WavyDot IdentifierName
CallExpression : ...
CallExpression WavyDot [ Expression ] Arguments
CallExpression WavyDot IdentifierName Arguments
MemberExpression WavyDot Arguments
CallExpression WavyDot Arguments
CallExpression WavyDot [ Expression ]
CallExpression WavyDot IdentifierName
A Babel playground implements this proposal using static methods on the HandledPromise
object that is in the current scope. The Work-In-Progress Babel pull request for this syntax is also available.