Skip to content
TC39 Wavy Dot ("~.") Proposal
Branch: master
Clone or download
Latest commit ba26544 Oct 15, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information. corrected link Oct 15, 2019
tildot-miniplayer.png miniplayer Oct 5, 2019


Pleasant Notation for Promise Pipelining

by Mark S. Miller (@erights), Chip Morningstar (@FUDCo), and Michael FIG (@michaelfig)


Presented to TC39 (Javascript standards committee), achieving stage 1.

Presentation to TC39



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.

Wavy Dot

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 ~. name = value p.[[SetSend]]('name', value)
delete p ~. name p.[[DeleteSend]]('name')
p ~. (...args) p.[[ApplySend]](args)
p ~. name(...args) p.[[ApplyMethodSend]]('name', args)
p ~. [prop] p.[[GetSend]](prop)
p ~. [prop] = value p.[[SetSend]](prop, value)
delete p ~. [prop] p.[[DeleteSend]](prop)
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.

Proposed Syntax

Abstract Syntax:

 Expression : ...
      Expression ~. [ Expression ] Arguments    // eventual post
      Expression ~. Arguments                   // eventual post
      Expression ~. [ Expression ]              // eventual get
      Expression ~. [ Expression ] = Expression // eventual put
      delete Expression ~. [ Expression ]       // eventual delete

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
  UnaryExpression : ...
      delete CallExpression WavyDot [ Expression ]
      delete CallExpression WavyDot IdentifierName
  LeftHandSideExpression :
      CallExpression [ Expression ]
      CallExpression . IdentifierName
      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.

You can’t perform that action at this time.