1 of 26

Type Annotation Delimiting Concerns

Waldemar Horwat

2 of 26

Example

function f(a, b, c, d) {

let async = a.async;

let flag = async < 4;

if (flag) {

while (async != 10) {

d += bar(async);

++async;

}

} else {

d = -d**2;

}

return flag ? d => (d) > (c) : d => d;

}

3 of 26

function f(a, b, c, d) {

let async = a.async;

let flag = async < 4;

if (flag) {

while (async != 10) {

d += bar(async);

++async;

}

} else {

d = -d**2;

}

return flag ? d => (d) > (c) : d => d;

}

Syntax error

4 of 26

Token Soup

function f(a, b, c, d) {

let async = a.async;

let flag = async < 4;

if (flag) {

while (async != 10) {

d += bar(async);

++async;

}

} else {

d = -d**2;

}

return flag ? d => (d) > (c) : d => d;

}

CoverCallExpressionAndAsyncArrowHead : MemberExpression TypeParametersopt Arguments TypeAnnotationopt

5 of 26

Type-Erased Version

function f(a, b, c, d) {

let async = a.async;

let flag = async (c) => d;

}

6 of 26

function f(a, b, c, d) {

let async = a.async;

let flag = async < 4;

if (flag) {

while (async != 10) {

d += bar(async);

++async;

}

} else {

d = -d**2;

}

return flag ? d => (d) > (c) : d => d;

}

Discuss later

Discuss later

7 of 26

Token Soup

Skip arbitrary sequence of tokens, only matching:

( … )

[ … ]

{ … }

< … >

Template literals

8 of 26

Token Soup

Skip arbitrary sequence of tokens, only matching:

Unknown how / vs. /regexp/ can be handled inside Token Soup (discuss later)

( … )

[ … ]

{ … }

< … >

Template literals

9 of 26

Token Soup

function map<Input, Output>(

arr: Input[], func: (arg: Input) => Output): (Output[]) {

return arr.map(func);

}

10 of 26

Token Soup Delimiting

function map<Input, Output>(

arr: Input[], func: (arg: Input) => Output): (Output[]) {

return arr.map(func);

}

Can we tell whether <, [, { starts a Token Soup or some other, non-type ECMAScript syntax?

11 of 26

Token Soup Delimiting

function map<Input, Output>(

arr: Input[], func: (arg: Input) => Output): (Output[]) {

return arr.map(func);

}

Can we tell whether <, [, { starts a Token Soup or some other, non-type ECMAScript syntax?

  1. Unambiguous from what precedes the <, [, {
  2. Backtracking: depends on what follows the Token Soup

12 of 26

Token Soup Backtracking

{a:b} => …

13 of 26

Token Soup Backtracking

{a:b} => …

… {yield / 3}; a = “4/} …

14 of 26

Token Soup Backtracking

{a:b} => …

… {yield / 3}; a = “4/} …

{yield / 3}; a = “4/} …

{yield / 3}; a = “4/}

15 of 26

Token Soup Delimiting

Can we tell whether <, [, { starts a Token Soup or some other, non-type ECMAScript syntax?

  • Unambiguous from what precedes the <, [, {
  • Backtracking: depends on what follows the Token Soup

16 of 26

Example 1

function f(a, b, c, d) {

let async = a.async;

let flag = async < 4;

if (flag) {

while (async != 10) {

d += bar(async);

++async;

}

} else {

d = -d**2;

}

return flag ? d => (d) > (c) : d => d;

}

CoverCallExpressionAndAsyncArrowHead : MemberExpression TypeParametersopt Arguments TypeAnnotationopt

17 of 26

Example 1

function f(a, b, c, d) {

let foo = a.async;

let flag = foo < 4;

if (flag) {

while (foo != 10) {

d += bar(foo);

++foo;

}

} else {

d = -d**2;

}

return flag ? d => (d) > (c) : d => d;

}

CoverCallExpressionAndAsyncArrowHead : MemberExpression TypeParametersopt Arguments TypeAnnotationopt

18 of 26

Example 2

a : (type) => (foo())

19 of 26

Example 2

a : (type) => (foo())

a : (type) => (foo())

ArrowFunction :

ArrowParameters : Type => ConciseBody

Type : ParenthesizedTokens

Token Soup

CoverParenthesizedExpressionAndArrowParameterList

20 of 26

Example 3

a : (type) => (foo())

a : (type) => (foo()) => …

ArrowFunction :

ArrowParameters : Type => ExpressionBody

Type : ParenthesizedTokens

Type : ParenthesizedTokens =>

ParenthesizedTokens

ExpressionBody

TokenSoup

21 of 26

Token Soups Don’t Work

Can we tell whether <, [, { starts a Token Soup or some other, non-type ECMAScript syntax?

  • Unambiguous from what precedes the <, [, {
  • Backtracking: depends on what follows the Token Soup

22 of 26

Token Soups Don’t Work

Can we tell whether <, [, { starts a Token Soup or some other, non-type ECMAScript syntax?

  • Unambiguous from what precedes the <, [, {
  • Backtracking: depends on what follows the Token Soup

Can’t embed constant arithmetic inside Token Soups

[limit / 2]

[a < b ? a : b]

23 of 26

Issues filed a year ago

24 of 26

Extra Reserved Words

expression as type

… as (…)

… as […]

… as {…}

RelationalExpression :

RelationalExpression as Type

Type : ParenthesizedTokens

Type : SquareBracketedTokens

Type : CurlyBracketedTokens

TokenSoup

25 of 26

Extra Reserved Words

module as {…}

RelationalExpression :

RelationalExpression as Type

Type : ParenthesizedTokens

Type : SquareBracketedTokens

Type : CurlyBracketedTokens

ModuleDeclaration :

module Identifier { ModuleBody }

TokenSoup

ModuleBody

26 of 26

Divergence from TS, Flow, Hegel, …