+ All Categories
Home > Documents > Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David...

Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David...

Date post: 14-Dec-2015
Category:
Upload: dylan-harper
View: 217 times
Download: 0 times
Share this document with a friend
90
Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research
Transcript
Page 1: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

DependentTypes for JavaScript

Ravi Chugh Ranjit JhalaUniversity of California, San Diego

David HermanMozilla Research

Page 2: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

DependentTypes for JavaScript

Why?

Pervasive

Used at Massive Scale

Page 3: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

3

Why Add Types?

var x = {};

x.f;

x.f.f;

produces undefined rather than error…

… but this raises TypeError

Page 4: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

4

Why Add Types?

There Are Run-time Errorsreading from undefined, applying non-function values, …

Worse: Browsers Hide Them!

var x = {};

x.f;

x.f.f;

Page 5: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

5

Why Add Types?

Prevent Errors

Prevent the Unexpected

Page 6: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

6

Okay, But Who Cares?

ProgrammersJSLint, Closure Compiler, TypeScript, Dart

Browser VendorsCompete based on performance, security, reliability

Standards CommitteesActively evolving JavaScript and Web standards

Page 7: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

DependentTypes for JavaScript

Why?

Isn’t the Language Terrible?

Page 8: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

8

JavaScript

implicit global object

scope manipulation

var lifting

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

Page 9: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

9

JavaScript

implicit global object

scope manipulation

var lifting

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

objects prototypes

lambdastype-tests

Page 10: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

10

JavaScript

“The Good Parts”

implicit global object

scope manipulation

var lifting

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

objects prototypes

lambdastype-tests

Page 11: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

11

JavaScript

“The Good Parts”

PriorType

Systems

Key Idea:Use Logic!

Our Approach

Page 12: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

12

JavaScript

“The Good Parts”

Dependent JavaScriptDJS

Page 13: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

13

Outline

Motivation

Our Approach: Logic!

Evaluation

Page 14: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

14

typeof true // “boolean”

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

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

Page 15: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

15

typeof returns run-time “tags”

Tags are very coarse-grained types

“undefined”

“boolean”

“string”

“number”

“object”

“function”

Page 16: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

16

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 17: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

17

{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 18: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

Refinement Types

18

3 :: {n|n = 3}

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

Page 19: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

Refinement Types

19

{n|n = 3}

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

<:<:<:<:

Subtyping is Implication

Page 20: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

Refinement Types

20

{n|n = 3}

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

Subtyping is Implication

Page 21: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

21

ArraysPrototypesMutable ObjectsDuck TypingTag-Tests

Page 22: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

22

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

}

negate( )

!true

true

// false

Page 23: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

23

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 24: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

24

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

}

negate( )

0 - [] // 0WAT?!

[]

Page 25: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

25

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 26: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

26

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 27: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

27

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 28: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

28

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 29: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

29

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

}

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

Page 30: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

30

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 31: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

31

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 32: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

32

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

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

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

}

Page 33: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

33

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

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

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

}

output type depends on input value

Page 34: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

34

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

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

Programmer choosesdegree of precision

in specification

Page 35: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

35

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 36: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

36

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 37: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

37

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 38: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

38

Duck Typing ArraysPrototypesMutable ObjectsTag-Tests

if (duck.quack)

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

else

return “This duck can’t quack!”;

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

{v|has(d,“quack”)

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

Operators from McCarthy theory of arrays

Page 39: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

39

Duck Typing ArraysPrototypesMutable ObjectsTag-Tests

if (duck.quack)

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

else

return “This duck can’t quack!”;

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

{v|has(d,“quack”)

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

Call produces Str, so concat well-typed

Page 40: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

40

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 41: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

41

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 42: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

42

ArraysPrototypesTag-Tests Duck Typing Mutable Objects

Page 43: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

43

ArraysPrototypesTag-Tests Duck Typing Mutable Objects

Typical“Dynamic”Features

Page 44: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

44

ArraysPrototypesTag-Tests Duck Typing Mutable Objects

Typical“Dynamic”Features

JavaScript

tl;dr

Harder, butDJS handles them

Page 45: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

45

Prototypes ArraysTag-Tests Mutable ObjectsDuck Typing

child

parent

...

grandpa

null

Upon construction, each object links to a

prototype object

Page 46: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

46

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 47: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

...

47

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 48: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

...

48

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 49: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

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

...

49

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 50: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

...

50

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 51: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

...

51

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 52: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

...

52

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 53: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

53

Prototypes ArraysTag-Tests Mutable ObjectsDuck Typing

Key Idea:

Reduce prototypesemantics to decidable

theory of arrays

Prototype Chain Unrolling

Page 54: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

54

ArraysTag-Tests PrototypesMutable ObjectsDuck Typing

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

A finite tuple…

… extended to unbounded collection

Page 55: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

55

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 56: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

56

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 57: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

57

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 58: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

58

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 59: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

59

ArraysTag-Tests PrototypesMutable ObjectsDuck Typing

DJS handles other quirks:

Special length property

Array.prototypeNon-integer keys

Page 60: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

60

Tag-Tests PrototypesMutable ObjectsDuck Typing Arrays

Page 61: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

61

What About eval?

Arbitrary code loading

eval(“…”);

Old Types

Page 62: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

62

What About eval?…

eval(“…”);

//: #assume

Old Types

New TypesNew Types

“Contract Checking” at Run-timeaka “Gradual Typing”

Page 63: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

63

Recap of DJS Techniques

Logic!

Path and Flow Sensitivity

Prototype Unrolling

Syntactic Sugar

Page 64: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

64

Outline

Motivation

Our Approach: Logic!

Evaluation

Page 65: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

65

“The Good Parts”

objects prototypes

lambdastype-tests

arrays

13 Benchmarks

Page 66: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

66

“The Good Parts”

objects prototypes

lambdastype-tests

arrays

13 Benchmarks

Page 67: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

67

“The Good Parts”

objects prototypes

lambdastype-tests

arrays

13 Benchmarks

Four inheritance patterns fromCrockford’s JS: The Good Parts

Page 68: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

68

“The Good Parts”

objects prototypes

lambdastype-tests

arrays

13 Benchmarks

Array-manipulating examplesfrom SunSpider

Page 69: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

69

“The Good Parts”

objects prototypes

lambdastype-tests

arrays

13 Benchmarks

typeOf() function to replace typeoffrom Closure Compiler

Page 70: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

70

“The Good Parts”

objects prototypes

lambdastype-tests

arrays

13 Benchmarks

Well-typed programsdon’t have run-time errors

Page 71: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

DesugaredProgram

DJSProgram

DesugarerBased on Guha et al.

[ECOOP 2010]

Implementation

JavaScript λ-Calculus + References + Prototypes

Page 72: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

DesugaredProgram

Z3 SMTSolver

TypeChecker

DJSProgram

DesugarerBased on Guha et al.

[ECOOP 2010]

ImplementationProgrammer Chooses

Warnings or Errors

Local Type Inference

Subtyping w/o Z3 If Possible

Page 73: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

Annotation Burden

+= ~300 LOC to start+= ~100 LOC annotations

=+ ~400 LOC total

(Improved since paper)

33% Annotation Overhead

Common Cases Simplified viaSyntactic Sugar and Local Type Inference

Page 74: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

Performance(Improved since paper)

Total benchmark suite:

~10 seconds~1100 Z3 queries

11/13 benchmarks in 0-1 s

Common Cases Fast viaSyntactic Reasoning When Possible

Page 75: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

75

Future Work

Syntax, Inference, Performance

Larger Examples

Type Checker in JS; Run in Browser

IDE Support for Refactoring, etc.

Page 76: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

76

JavaScript

“The Good Parts”

Types via Logic!DJS

Page 77: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

Thanks!

77

ravichugh.com/djs

D::PS: I’m on the Job Market

Page 78: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

78

Extra Slides

Page 79: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

Coq

refinement types

dependent types

Expressivity

“Usability”

JS

+ nested refinements

System D[POPL ’12]

DJS

DependentJavaScript

[this paper]

syntactic types

occurrence types

∨, ∧

F≤

Page 80: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

System D [POPL 2012]+ Types for JS Primitives+ Strong Updates+ Quirky JS Arrays+ Prototype Inheritance

Dependent JavaScript (DJS)

Page 81: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

81

/*: x:NumOrBool {ite Num(x) Num(v) Bool(v)} */

function negate(x) { x = (typeof x == “number”) ? 0 – x : !x return x}

/*: x:Any {v iff falsy(x)} */

function negate(x) { x = (typeof x == “number”) ? 0 – x : !x return x}

Function Types and Objects{p} {v|p}

Page 82: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

82

ObjHas(d,k,H,d’) has(d,k) HeapHas(H,d’,k)

/*: x:Ref / [x |-> d:Dict |> x.pro] {v iff ObjHas(d,”f”,curHeap,x.pro)} / sameHeap */

function hasF(x) { return “f” in x}

x:T1/H1 T2/H2

Function Types and Objects

output typeinput heap

input type output heap

Page 83: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

83

ObjSel(d,k,H,d’) ite has(d,k) sel(d,k) HeapSel(H,d’,k)

x:T1/H1 T2/H2

Function Types and Objects

output typeinput heap

input type output heap

/*: x:Ref / [x |-> d:Dict |> x.pro] {v = ObjSel(d,”f”,curHeap,x.pro)} / sameHeap */

function readF(x) { return x.f}

Page 84: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

84

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

}

negate( )

0 - “2”// -2

“2”

Whoa, but perhaps okay…

Page 85: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

85

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

}

negate( )

0 - undefined// NaN

undefinedError would be nicer,

but okay…

Page 86: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

86

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

}

negate( )

0 - {}// NaN

{}

Seems about right…

Page 87: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

87

Tag-Tests ArraysPrototypesMutable ObjectsDuck Typing

var negate = function(x) {

if (typeof x == “boolean”)

return !x;

else

return 0 - x;

}

negate( )

0 - [] // 0

[]

WAT?!

negate has good intentionsBut too many corner cases in JS semantics!

Page 88: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

88

Duck Typing ArraysPrototypesMutable ObjectsTag-Tests

if (duck.quack)

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

else

return “This duck can’t quack!”;

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

{v|has(d,“quack”)

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

Function types nested inside refinements

[POPL 2012]

Page 89: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

89

ArraysPrototypesTag-Tests Duck Typing

var x = {};

x.f;

x.f.f; Programmer configures DJS to report either

warnings or errors for:

1) Possible unbound keys

Mutable Objects

Page 90: Dependent Types for JavaScript Ravi Chugh Ranjit Jhala University of California, San Diego David Herman Mozilla Research.

90

ArraysPrototypesTag-Tests Duck Typing

var x = {};

x.f;

x.f.f; Programmer configures DJS to report either

warnings or errors for:

1) Possible unbound keys

2) Possible run-time errors

Mutable Objects


Recommended