Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD...

78
Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD UCSD Mozil la Googl e UCSD

Transcript of Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD...

Page 1: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

DependentTypes for JavaScript

Ravi ChughRanjit JhalaDave HermanPat RondonPanos Vekris

UCSDUCSDMozillaGoogleUCSD

Page 2: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

DependentTypes for JavaScript

“Dynamic” Features Facilitate Rapid Innovation

1. Better Development Tools

2. Better Reliability

3. Better Performance

Page 3: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

var person = { name : { first : “John”, last : “McCarthy” }};

person.nom;

person.nom.first;

… but this raises TypeError3

produces undefined rather than error…

Page 4: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

var person = { name : { first : “John”, last : “McCarthy” }};

person.nom;

person.nom.first;

4

if (unlikely()) {

}

some errors hard to catch with testing

Page 5: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

DependentTypes for JavaScript

Will Never Replace Need forTesting and Dynamic Checking

But Want Static Checking When Possible

Page 6: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

6

JavaScript

implicit global object

scope manipulation

var lifting

‘,,,’ == new Array(4)

Page 7: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

7

JavaScript

implicit global object

scope manipulation

var lifting

‘,,,’ == new Array(4)

objects prototypes

lambdastype-tests

“The Good Parts” arrays

eval()

Page 8: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

8

JavaScript

“The Good Parts”

Dependent JavaScript

Use Logic, butAvoid Quantifiers!

Page 9: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

9Expressiveness

“Usability”

F* + Dijkstra

TypedJS

Nik@9:00am

Shriram@2:30pm

Me@now

Dependent JavaScript (DJS)[POPL ’12, OOPSLA ’12]

Page 10: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

10

Me@now

Dependent JavaScript (DJS)[POPL ’12, OOPSLA ’12]

= Refinement Types+ Several New Quantifier-Free Mechanisms

DJS

Page 11: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

11

typeof true // “boolean”

typeof 0.1 // “number”typeof 0 // “number”

typeof {} // “object”typeof [] // “object”typeof null // “object”

Page 12: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

12

typeof returns run-time “tags”

Tags are very coarse-grained types

“undefined”

“boolean”

“string”

“number”

“object”

“function”

Page 13: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

13

Refinement Types{x|p}

“set of values x s.t. formula p is true”

{n|tag(n) = “number” }Num

{v|tag(v) = “number” ∨ tag(v) = “boolean” }NumOrBool

{i|tag(i) = “number” integer(i) }Int

{x|true }Any

Page 14: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

14

{n|tag(n) = “number” }Num

{v|tag(v) = “number” ∨ tag(v) = “boolean” }NumOrBool

{i|tag(i) = “number” integer(i) }Int

{x|true }Any

Refinement Types

Syntactic Sugarfor Common Types

Page 15: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

Refinement Types

15

3 :: {n|n = 3}

{n|n > 0} 3 ::{n|tag(n) = “number” integer(n)} 3 ::{n|tag(n) = “number”} 3 ::

Page 16: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

Refinement Types

16

{n|n = 3}

{n|n > 0} {n|tag(n) = “number” integer(n)} {n|tag(n) = “number” }

<:<:<:<:

Subtyping is Implication

Page 17: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

Refinement Types

17

{n|n = 3}

{n|n > 0} {n|tag(n) = “number” integer(n)} {n|tag(n) = “number” }

Subtyping is Implication

Page 18: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

18

ArraysPrototypesMutable ObjectsDuck TypingTag-Tests

Page 19: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

19

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

}

negate( )

!true

true

// false

Page 20: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

20

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

}

negate( )

0 - 2 // -2

2

Page 21: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

21

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

}

negate( )

0 - [] // 0?!?

[]

Page 22: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

22

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

} Use types to prevent implicit coercion

(-) :: (Num,Num) Num

Page 23: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

23

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

}

Function type annotation inside

comments

//: negate :: (x:Any) Any

Page 24: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

24

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

}

//: negate :: (x:Any) Any

so negationis well-typed

x is boolean...

DJS is Path Sensitive

Page 25: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

25

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

}

//: negate :: (x:Any) Any

x is arbitrarynon-boolean value…so DJS signals error!

DJS is Path Sensitive

Page 26: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

26

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

}

//: negate :: (x:NumOrBool) Any

Page 27: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

27

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

}

//: negate :: (x:NumOrBool) Any

this time,x is a number…✓so subtractionis well-typed

Page 28: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

28

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

}

//: negate :: (x:NumOrBool) Any✓

but returntype is imprecise

Page 29: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

29

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

//: negate :: (x:NumOrBool) NumOrBool

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

}

Page 30: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

30

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

/*: negate :: (x:NumOrBool) {y|tag(y) = tag(x)} */

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

}

output type depends on input value

Page 31: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

31

Duck Typing ArraysPrototypesMutable ObjectsTag-Tests

if (duck.quack)

return “Duck says ” + duck.quack();

else

return “This duck can’t quack!”;

What is “Duck Typing”?

Page 32: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

32

Duck Typing ArraysPrototypesMutable ObjectsTag-Tests

if (duck.quack)

return “Duck says ” + duck.quack();

else

return “This duck can’t quack!”;

What is “Duck Typing”?

(+) :: (Num,Num) Num

(+) :: (Str,Str) Str

Page 33: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

33

Duck Typing ArraysPrototypesMutable ObjectsTag-Tests

if (duck.quack)

return “Duck says ” + duck.quack();

else

return “This duck can’t quack!”;

What is “Duck Typing”?

Can dynamically testthe presence of a method

but not its type

Page 34: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

34

Duck Typing ArraysPrototypesMutable ObjectsTag-Tests

if (duck.quack)

return “Duck says ” + duck.quack();

else

return “This duck can’t quack!”;

{d|tag(d) = “object”∧

{v|has(d,“quack”)

{v| sel(d,“quack”) :: UnitStr }

Operators from McCarthy theory of arrays

Page 35: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

35

Duck Typing ArraysPrototypesMutable ObjectsTag-Tests

if (duck.quack)

return “Duck says ” + duck.quack();

else

return “This duck can’t quack!”;

{d|tag(d) = “object”∧

{v|has(d,“quack”)

{v| sel(d,“quack”) :: Unit Str }

Call produces Str, so concat well-typed

Page 36: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

36

Mutable Objects ArraysPrototypesTag-Tests Duck Typing

var x = {};

x.f = 7;

x.f + 2;

x0:Empty

x1:{d|d = upd(x0,“f”,7)}

DJS is Flow Sensitive

McCarthy operatorDJS verifies that x.f is definitely a number

Page 37: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

37

Mutable Objects ArraysPrototypesTag-Tests Duck Typing

var x = {};

x.f = 7;

x.f + 2;

x0:Empty

x1:{d|d = upd(x0,“f”,7)}

DJS is Flow Sensitive

Strong updates to singleton objects

Weak updates to collections of objects

Page 38: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

38

ArraysPrototypesTag-Tests Duck Typing Mutable Objects

Page 39: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

39

ArraysPrototypesTag-Tests Duck Typing Mutable Objects

Typical“Dynamic”Features

Page 40: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

40

ArraysPrototypesTag-Tests Duck Typing Mutable Objects

Typical“Dynamic”Features

JavaScript

Page 41: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

41

Prototypes ArraysTag-Tests Mutable ObjectsDuck Typing

child

parent

...

grandpa

null

Upon construction, each object links to a

prototype object

Page 42: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

42

Prototypes ArraysTag-Tests Mutable ObjectsDuck Typing

If child contains k, then Read k from child

Else if parent contains k, then Read k from parent

Else if grandpa contains k, then Read k from grandpa

Else if …

Else Return undefined

child

parent

...

grandpa

null

var k = “first”; child[k];Semantics of Key Lookup

Page 43: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

...

43

Prototypes ArraysTag-Tests Mutable ObjectsDuck Typing

child

parent

grandpa

null

H(Rest of Heap)

var k = “first”; child[k];Semantics of Key Lookup

If child contains k, then Read k from child

Else if parent contains k, then Read k from parent

Else if grandpa contains k, then Read k from grandpa

Else if …

Else Return undefined

{v|if has(child,k) then

{v|ifv=sel(child,k)

Page 44: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

...

44

Prototypes ArraysTag-Tests Mutable ObjectsDuck Typing

child

parent

grandpa

null

H(Rest of Heap)

var k = “first”; child[k];Semantics of Key Lookup

If child contains k, then Read k from child

Else if parent contains k, then Read k from parent

Else if grandpa contains k, then Read k from grandpa

Else if …

Else Return undefined

{v|if has(child,k) then

{v|ifv=sel(child,k)

{v|else if has(parent,k) then

{v|ifv=sel(parent,k)

Page 45: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

If child contains k, then Read k from child

Else if parent contains k, then Read k from parent

Else if grandpa contains k, then Read k from grandpa

Else if …

Else Return undefined

...

45

Prototypes ArraysTag-Tests Mutable ObjectsDuck Typing

{v|if has(child,k) then

{v|ifv=sel(child,k)

{v|else if has(parent,k) then

{v|ifv=sel(parent,k)

child

parent

grandpa ???

null

H(Rest of Heap)

var k = “first”; child[k];Semantics of Key Lookup

Page 46: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

...

46

Prototypes ArraysTag-Tests Mutable ObjectsDuck Typing

{v|if has(child,k) then

{v|ifv=sel(child,k)

{v|else if has(parent,k) then

{v|ifv=sel(parent,k)

{v|else

{v|ifv=HeapSel(H,grandpa,k)) }

child

parent

grandpa ???

null

H(Rest of Heap)

var k = “first”; child[k];Semantics of Key Lookup

Abstract predicateto summarize theunknown portion

of the prototype chain

Page 47: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

...

47

Prototypes ArraysTag-Tests Mutable ObjectsDuck Typing

{v|if has(child,k) then

{v|ifv=sel(child,k)

{v|else if has(parent,k) then

{v|ifv=sel(parent,k)

{v|else

{v|ifv=HeapSel(H,grandpa,k)) }

{ “first” : “John” }child

parent{ “first” : “Ida”, “last” : “McCarthy” }

grandpa ???

null

H(Rest of Heap)

<:

{v|v=“John”}

var k = “first”; child[k];

Page 48: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

...

48

Prototypes ArraysTag-Tests Mutable ObjectsDuck Typing

{v|if has(child,k) then

{v|ifv=sel(child,k)

{v|else if has(parent,k) then

{v|ifv=sel(parent,k)

{v|else

{v|ifv=HeapSel(H,grandpa,k)) }

{ “first” : “John” }child

parent{ “first” : “Ida”, “last” : “McCarthy” }

grandpa ???

null

H(Rest of Heap)

var k = “last”; child[k];

<:

{v|v=“McCarthy”}

Page 49: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

49

Prototypes ArraysTag-Tests Mutable ObjectsDuck Typing

Key Idea:

Reduce prototypesemantics to decidable

theory of arrays

Prototype Chain Unrolling

Page 50: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

50

ArraysTag-Tests PrototypesMutable ObjectsDuck Typing

var nums = [0,1,2];while (…) { nums[nums.length] = 17;}

A finite tuple…

… extended to unbounded collection

Page 51: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

51

ArraysTag-Tests PrototypesMutable ObjectsDuck Typing

var nums = [0,1,2];while (…) { nums[nums.length] = 17;}

delete nums[1];

for (i = 0; i < nums.length; i++) { sum += nums[i];}

A “hole” in the array

Missing element within “length”

Page 52: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

52

ArraysTag-Tests PrototypesMutable ObjectsDuck Typing

Track types, “packedness,” and lengthof arrays where possible

{a |a :: Arr(T)

{a | packed(a)

{a | len(a) = 10}

X T T T T… X ……

T? T? T? T? T?… T? ……

T? { x | T(x) x = undefined }

-1 0 1 2 len(a)

X { x | x = undefined }

Page 53: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

53

ArraysTag-Tests PrototypesMutable ObjectsDuck Typing

{a |a :: Arr(Any)

{a | packed(a) len(a) = 2

{a | Int(sel(a,0))

{a | Str(sel(a,1))}

Encode tuples as arrays

var tup = [17, “cacti”];

Page 54: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

54

ArraysTag-Tests PrototypesMutable ObjectsDuck Typing

var tup = [17, “cacti”];

tup[tup.length] = true;

{a |a :: Arr(Any)

{a | packed(a) len(a) = 3

{a | …}

Page 55: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

55

ArraysTag-Tests PrototypesMutable ObjectsDuck Typing

DJS handles other array quirks:

Special length property

Array.prototypeNon-integer keys

Page 56: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

56

Tag-Tests PrototypesMutable ObjectsDuck Typing Arrays

Page 57: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

57

What About eval?

Arbitrary code loading

eval(“…”);

Old Types

Page 58: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

58

What About eval?…

eval(“…”);

//: #assume

Old Types

New TypesNew Types

Can Integrate DJS with“Contract Checking” at Run-time

aka “Gradual Typing”

Page 59: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

59

Dependent JavaScript (DJS)[POPL ’12, OOPSLA ’12]

Expressiveness

“Usability”

F* + Dijkstra

= Refinement Types+ Nested Refinements+ Flow Sensitive Types+ Prototype Unrolling+ Array Encoding

DJS

Quantifier-Free Mechanisms}

Page 60: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

60

Function Subtyping…{d|sel(d,“f”) :: }

(x:Any) { y|y = x }{d|sel(d,“f”) :: }(x:Num) Num<:

Page 61: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

61

Function Subtyping…

{d|sel(d,“f”) :: }(x:Num) Num

{d|sel(d,“f”) :: } (x:Any) { y|y = x }

Page 62: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

62

Function Subtyping…

{d|sel(d,“”)f :: }(x:Num) Num

{d|sel(d,“ ”f :: } (x:Any) { y|y = x }

… With Quantifiers∀x,y. true ∧ y = f(x) y = x

∀x,y. Num(x) ∧ y = f(x) Num(y)✓Valid, but First-Order Logic is Undecidable

Page 63: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

63

Function Subtyping…

{d|sel(d,“”)f :: }(x:Num) Num

{d|sel(d,“ ”f :: } (x:Any) { y|y = x }

… Without Quantifiers!Nested Refinements

Treat Function Types as Uninterpreted

Implication = SMT Validity + Syntactic Subtyping

Page 64: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

64

Heap Updates…

… With Quantifiers

var x = {};

x.f = 7;h1

h2

h0

∧ …

∧ sel(h1,x) = empty∧ ∀y. x ≠ y sel(h1,y) = sel(h0,y)

∧ sel(h2,x) = upd(sel(h1,x),“f”,7)∧ ∀y. x ≠ y sel(h2,y) = sel(h1,y)

Encode Heap w/ McCarthy Operators

Page 65: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

65

Heap Updates…

x:T1/H1 T2/H2

output typeinput heap

input type output heap

Flow-Sensitive Types (à la Alias Types)

var x = {};

x.f = 7;h1

h2

h0

… Without Quantifiers!

Page 66: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

66

Prototype Inheritance…

… Without Quantifiers!

Array Semantics…

Page 67: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

67

Dependent JavaScript (DJS)[POPL ’12, OOPSLA ’12]

Expressiveness

“Usability”

F* + Dijkstra

= Refinement Types+ Nested Refinements+ Flow Sensitive Types+ Prototype Unrolling+ Array Encoding

DJS

Quantifier-Free Mechanisms}

Page 68: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

DesugaredProgram

DJSProgram

DesugarerBased on Guha et al.

[ECOOP ’10]

JavaScript λ-Calculus + References + Prototypes

Implementation

Page 69: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

DesugaredProgram

Z3 SMTSolver

TypeChecker

DJSProgram

DesugarerBased on Guha et al.

[ECOOP ’10]

ImplementationProgrammer Chooses

Warnings or Errors

Local Type Inference

Subtyping w/o Z3 If Possible

Page 70: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

70

306a

408(+33%)

LOCbefore/after

13 Excerpts from: JavaScript, Good Parts SunSpider Benchmark Suite Google Closure Library

Benchmarks

Chosen to Stretch the Current Limits of DJS

Page 71: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

71

306a

408(+33%)

LOCbefore/after

13 Excerpts from: JavaScript, Good Parts SunSpider Benchmark Suite Google Closure Library

Benchmarks

9 Browser Extensions from: [Guha et al. Oakland ’11]

321a

383(+19%)

1,003a

1,027(+2%)

2 Examples from: Google Gadgets

1,630

1,818(+12%)

TOTALS

Page 72: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

72

1,630

1,818(+12%)

TOTALS

Already Improved by SimpleType Inference and Syntactic Sugar

Plenty of Room for Improvement• Iterative Predicate Abstraction• Bootstrap from Run-Time Traces

1,818(+12%)

Page 73: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

73

LOCbefore/after

13 Excerpts from: JavaScript, Good Parts SunSpider Benchmark Suite Google Closure Library

306a

408(+33%)

Benchmarks

9 Browser Extensions from: [Guha et al. Oakland ’11]

321a

383(+19%)

2 Examples from: Google Gadgets

1,003a

1,027(+2%)

1,630

1,818(+12%)

10 sec

Running Time

3 sec

19 sec

32 sec

TOTALS

Page 74: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

74

1,818(+12%)

32 sec

Already Improved by SimpleOptimizations• Avoid SMT Solver When Possible• Reduce Precision for Common Patterns

Plenty of Room for Improvement

1,630

TOTALS

32 sec

Page 75: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

DependentTypes for JavaScript

1. Better Development Tools

2. Better Reliability

3. Better Performance

Page 76: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

76Expressiveness

“Usability”

F* + Dijkstra

TypedJS

Dependent JavaScript (DJS)[POPL ’12, OOPSLA ’12]

TypeScriptLightweight (unsound) static checking tools becoming popular

Opportunityto improveIDE tools

Page 77: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

77

Reliability / Security• Refinement types for security in presence of

untrusted code (e.g. browser extensions)• Combine with static reasoning for JavaScript

Performance• JITs use static analysis + profiling to optimize

dynamic features (e.g. dictionaries, bignums)• Opportunity to enable more optimizations

Page 78: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala Dave Herman Pat Rondon Panos Vekris UCSD Mozilla Google UCSD.

DependentTypes for JavaScript

1. Better Development Tools

2. Better Reliability

3. Better Performance

DJS is a StepTowards

These Goals}

Thanks!

ravichugh.com/djs