towards dependent types for javascript ravi chugh, david herman, ranjit jhala university of...

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

Upload: kathlyn-hall

Post on 17-Dec-2015

215 views

Category:

Documents


0 download

TRANSCRIPT

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

Towards Dependent Types for JavaScript

Ravi Chugh, David Herman, Ranjit Jhala

University of California, San DiegoMozilla Research

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

Towards Dependent Types for JavaScript

A Large Subset ofExplicit

Decidable

Features Common to All Editions

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

3

Challenges

Our Approach

Preliminary Results

Outline

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

4

Challenge 1: Reflection

function negate(x) { if (typeof x == “number”) return 0 - x else return !x}

x should be “num-or-bool”

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

5

Challenge 2: Mutation

function negate(x) { if (typeof x == “number”) x = 0 - x else x = !x return x}

Different types stored in x

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

6

Challenge 3: Coercions

3 + 4 // 7

“3” + “4” // “34”

3 + “4” // “34”

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

7

Challenge 3: Coercions

!true // false

!1 // false

!“” // true

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

8

Challenge 3: Coercions

0 === 0 // true

0 === “” // false

0 == “” // true

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

9

Challenge 4: Objects

var par = {}var child = Obj.create(par)child.f = 1

var g = “g”child[g] = 2child.g // 2

child.h // undefinedpar.h = 3child.h // 3

Mutable

Dynamic Keys

Prototypes

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

10

Challenge 5: Arrays

var nums = [0,1,2]nums[0] + nums[1] + nums[2]

delete nums[1]

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

nums.push(42)

Finite or Unknown “Length”

“Packed” or “Unpacked”

Prototype-based

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

occurrence types

∨, ∧

F≤

Coq

refinement types

syntactic types dependent types

Expressivity

Usability

Prior Approaches

The JS Wall

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

12

Outline

Challenges

Our Approach

Preliminary Results

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

occurrence types

∨, ∧

F≤

Coq

refinement types

syntactic types dependent types

Expressivity

Usability

Our Approach

The JS Wall

+ nesting

System D[POPL ’12]

+this talk

DependentJavaScript

[in submission]

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

14

Refinement Types{x|p}

“value x such that formula p is true”{b|tag(b) = “boolean” }

Bool

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

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

{x|true }Any

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

15

Refinement Types{x|p}

“value x such that formula p is true”

Num3 ::

Int3 ::

{i|i > 0 }3 ::

{i|i = 3 }3 ::

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

16

Subtyping is Implication

{i|i = 3 } <: {i| i > 0 } <: Int <: Num

i = 3

i > 0

tag(i) = “number” integer(i)

tag(i) = “number”

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

17

Subtyping is Implication

LogicalSolver

AnnotatedProgram

TypeChecker

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

18

System D [POPL 2012]

var obj = { “n”: 17, “f”: function (i) { return i + 5 }}

{d|tag(d) = “Dict”

tag(sel(d,“n”)) = “number”

sel(d,“f”) :: Int Int }

obj ::

McCarthy’s decidable theory of arrays Great for dictionaries

of base values

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

19

System D [POPL 2012]

var obj = { “n”: 17, “f”: function (i) { return i + 5 }}

{d|tag(d) = “Dict”

tag(sel(d,“n”)) = “number”

sel(d,“f”) :: Int Int }

obj ::

Uninterpreted“has-type” predicate

Type constructors in formulas

Subtyping algorithm retains precision and decidability

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

System D [POPL 2012]

Dependent JavaScript (DJS)photo courtesy of ClipArt ETC

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

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

Dependent JavaScript (DJS)

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

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

Dependent JavaScript (DJS)

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

+ Types for JS Primitives+ Strong Updates+ Prototype Inheritance+ Arrays

Primitives Strong Updates Prototypes Arrays

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

24

! :: Bool Boolalse then b=true else b=false}

Primitives Strong Updates Prototypes Arrays

Choose degree ofprecision and coercion

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

25

! :: x:Bool {b | if x=false then b=true else b=false}

Primitives Strong Updates Prototypes Arrays

Choose degree ofprecision and coercion

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

26

! :: x:Any {b | if falsy(x) then b=true else b=false}

x = false x = 0 x = null x = “” x = undefined x = NaN

falsy(x)

Choose degree ofprecision and coercion

Primitives Strong Updates Prototypes Arrays

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

27

function negate(x) {

if (typeof x == “number”)

x = 0 - x

else

x = !x

return x

}

NumOrBool NumOrBool

x:NumOrBool {y |tag(y) =tag(x)}

PathSensitive

FlowSensitive

Strong UpdatesPrimitives Prototypes Arrays

(even with ordinary refinement types)

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

28

PrototypesPrimitives Strong Updates Arrays

var grandpa = …,

parent = Object.create(grandpa),

child = Object.create(parent),

b = k in child,

{v|v=true iff

(has(child,k)

(has(parent,k)

(has(grandpa,k)

(HeapHas(H,great,k)) }

grandpa

child

parent

Key Membership via Prototype Chain

Unrolling

b ::

H (Rest of Heap)

great

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

PrototypesPrimitives Strong Updates Arrays

var grandpa = …,

parent = Object.create(grandpa),

child = Object.create(parent),

b = k in child,

x = child[k]

{v|if has(child,k) then v=sel(child,k)

{v|elif has(parent,k) then v=sel(parent,k)

{v|elif has(grandpa,k) then v=sel(grandpa,k)

{v|elif HeapHas(H,great,k)) then v=HeapSel(H,great,k))

{v|else v=undefined }

Key Lookup viaPrototype Chain

Unrolling

x ::

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

30

PrototypesPrimitives Strong Updates Arrays

Key Idea

Reduce prototype semanticsto decidable theory of arrays

via flow-sensitivity and unrolling

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

ArraysPrimitives Strong Updates Prototypes

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

32

ArraysPrimitives Strong Updates Prototypes

Encode tuples as arrays

{a |a :: Arr(Any)

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

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

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

var tup = [17, “ni hao”]

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

33

ArraysPrimitives Strong Updates Prototypes

{a |a :: Arr(Any)

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

{a | … }

var tup = [17, “ni hao”]

tup.push(true) a

Re-use prototype mechanism

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

34

Recap of DJS Tricks

Uninterpreted Functions

Flow Sensitivity

Prototype Unrolling

Refinement Type Encodings

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

35

Outline

Challenges

Our Approach

Preliminary Results

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

DesugaredProgram

Z3 SMTSolver

TypeChecker

DJSProgram

DesugarerBased on Guha et al.

[ECOOP ’10]

~6 KLOC OCaml

Implementation

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

DesugaredProgram

Z3 SMTSolver

TypeChecker

DJSProgram

DesugarerBased on Guha et al.

[ECOOP ’10]

Mainly SunSpider and JSGP

300 Unannotated LOC70% Annotation overhead

9 Benchmarks run in <3s4 Benchmarks run in 8-52s

Benchmarks

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

DesugaredProgram

Z3 SMTSolver

TypeChecker

DJSProgram

DesugarerBased on Guha et al.

[ECOOP ’10]

All parts of type system used

Can optimize patternsduring desugaring

Can optimize patternsduring type checking

Evaluation

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

39

Conclusion

DJS is a steptowards climbing

the JS Wall

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

40

Thanks!

ravichugh.com/nested

D::github.com/ravichugh/djs

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

41

/*: 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}

{p} {v|p}

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

42

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

/*: x:Ref / [x |-> d:Dict |> ^x] {v iff ObjHas(d,”f”,curHeap,^x)} / 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 43: Towards Dependent Types for JavaScript Ravi Chugh, David Herman, Ranjit Jhala University of California, San Diego Mozilla Research

43

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] {v = ObjSel(d,”f”,curHeap,^x)} / sameHeap */

function readF(x) { return x.f}

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

44

Q: What is “Duck Typing”?

Structural Object Types+

Logical Reasoning ?