142
Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

Embed Size (px)

Citation preview

Page 1: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

Nested RefinementTypes for JavaScript

Ravi Chugh

Dissertation Defense − September 3, 2013

Page 2: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

Types for JavaScript

“Dynamic” or UntypedFatures Enable

Rapid Prototyping

2

Page 3: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

Types for JavaScript

“Dynamic” or UntypedFatures Enable

Rapid Prototyping

http://stackoverflow.com/tags02-03-13

Count Tag411,345 C#361,080 Java337,896 PHP321,757 JavaScript175,765 C++160,768 Python

83,486 C64,345 Ruby

9,827 Haskell1,347 OCaml

3

Page 4: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

Types for JavaScript

“Dynamic” or UntypedFatures Enable

Rapid Prototyping

1. Development Tools2. Reliability & Security

3. Performance

4

Page 5: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

5

1. Development Tools

optional “type systems”unsound but provide

some IDE support

Page 6: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

6

2. Reliability & Securitylightweight static checkers

run-time invariant checkers

secure language subsets

Page 7: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

7

3. Performancefast language subset

to facilitate optimizations

Just-In-Time (JIT) enginesperform static/dynamic analysis to predict types

Page 8: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

8

Types for JavaScript

Why So Hard?

Page 9: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

9

implicit global object

scope manipulationJavaScript

var lifting

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

Page 10: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

“The Good Parts”

objects

reflection

arrays

eval()*

lambdas

JavaScript

implicit global object

scope manipulation

var lifting

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

10

Page 11: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

“The Good Parts”

objects

reflection

arrays

eval()*

lambdas

JavaScript

11

Page 12: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

12Expressiveness

Usability Idioms ofDynamic Languages

Types

VerificationHoare Logics

Model CheckingAbstract Interpretation

Theorem Proving…

+ Logic

Thesis Statement:

“Refinement typescan reason about

dynamic languages to verify the absence of

run-time errors …

Page 13: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

13Expressiveness

Usability Idioms ofDynamic Languages

Types

VerificationHoare Logics

Model CheckingAbstract Interpretation

Theorem Proving…

+ Logic

Thesis Statement:

… without resortingto undecidable

logics”

Page 14: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

14Expressiveness

Usability Idioms ofDynamic Languages

Types

VerificationHoare Logics

Model CheckingAbstract Interpretation

Theorem Proving…

+ LogicDependent

JavaScript (DJS)[POPL 2012, OOPSLA 2012]

Page 15: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

15

OutlineMotivation and Thesis

Challenges of Dynamic LanguagesTour of Dependent JavaScript

Technical ContributionsEvaluation

Looking Ahead

Page 16: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

“The Good Parts”

objects

reflection

arrays

eval()*

lambdas

JavaScript

16

Page 17: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

Core Technical Challenges

reflection

17

objects

Page 18: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

Core Technical Challenges

JavaJavaScript

vs.

18

Page 19: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

JavaScriptfunction negate(x) {

if (typeof x == “number”) {

return 0 - x;

} else {

return !x;

} }

run-timetype-test

19

Page 20: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

JavaScriptfunction negate(x) {

if (typeof x == “number”) {

return 0 - x;

} else {

return !x;

} }

but booleanon else-branch

x should numbericon then-branch…

20

Page 21: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

JavaScriptfunction negate(x) {

if (typeof x == “number”) {

return 0 - x;

} else {

return !x;

} }Java

✗21

Page 22: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

Javainterface NumOrBool { NumOrBool negate(); }

class Bool implements NumOrBool { boolean data; Bool(boolean b) { this.data = b; }

Bool negate() { return new Bool(!this.data);} }

class Num implements NumOrBool { … }

declared union type

22

Page 23: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

JavaScriptfunction negate(x) {

if (typeof x == “number”) {

} else {

} }Javainterface NumOrBool {

NumOrBool negate(); }

class Bool implements NumOrBool { boolean data; Bool(boolean b) { this.data = b; }

Bool negate() { return new Bool(!this.data);} }

class Num implements NumOrBool { … }

ad-hoc union type

declared union type

23

Page 24: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

JavaScript

ML, Haskell a

function negate(x) {

if (typeof x == “number”) {

} else {

} }

24

datatype NumOrBool = | Num (n:number) | Bool (b:boolean)

let negate x = match x with | Num n Num (0 – n) | Bool b Bool (!b)

declared union type

ad-hoc union type

Page 25: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

JavaScriptfunction negate(x) {

if (typeof x == “number”) {

} else {

} }

Lightweight Reflection

25

ad-hoc union type

Page 26: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

Javaclass Person {

String first; String last;

Person (String s1, String s2) { this.first = s1; this.last = s2; }

void greeting(…) { … }}

var john = new Person(“John”, “McCarthy”);

var s = john.first + “…”;

var john = { “first” : “John”, “last” : “McCarthy”, “greeting” : … };

var s = john.first + “…”;

JavaScript

field names are declared

keys are arbitrary computed strings

26

Page 27: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

var john = { “first” : “John”, “last” : “McCarthy”, “greeting” : … };

var s = john.first + “…”;

JavaScript

john[“first”]

obj.f means obj[“f”]

Objects are Dictionaries

27

Javaclass Person {

String first; String last;

Person (String s1, String s2) { this.first = s1; this.last = s2; }

void greeting(…) { … }}

var john = new Person(“John”, “McCarthy”);

var s = john.first + “…”;

Page 28: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

Javaclass Person {

String first; String last;

Person (String s1, String s2) { this.first = s1; this.last = s2; }

void greeting(…) { … }}

var john = new Person(“John”, “McCarthy”);

var s = john.first + “…”;

var john = {};

john.first = “John”;john.last = “McCarthy”;john.greeting = …;

JavaScript

incrementally extend object

“sealed” after initialization

28

Page 29: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

var john = {};

john.first = “John”;john.last = “McCarthy”;john.greeting = …;

// much later in the codejohn.anotherKey = …;

addMoreKeys(john);

if (…) { addEvenMoreKeys(john);}

JavaScript

Objects are Extensible

29

Javaclass Person {

String first; String last;

Person (String s1, String s2) { this.first = s1; this.last = s2; }

void greeting(…) { … }}

var john = new Person(“John”, “McCarthy”);

var s = john.first + “…”;

Page 30: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

Java

30

class Person {

String first; String last;

Person (String s1, String s2) { this.first = s1; this.last = s2; }

void greeting(…) { … }}

var john = new Person(“John”, “McCarthy”);

var s = john.first + “…”;

class TuringWinner extends Person {

int year; TuringWinner (…) { … }}

var twJohn = new TuringWinner(…);

twJohn.greeting();

inherit fromsuperclass

Page 31: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

Java

31

class Person {

String first; String name;

Person (String s1, String s2) { this.first = s1; this.last = s2; }

void greeting(…) { … }}

var john = new Person(“John”, “McCarthy”);

...... s = john.first + “…”;

class TuringWinner extends Person {

int year; TuringWinner (…) { … }}

var twJohn = new TuringWinner(…);

twJohn.greeting();

inheritance chaindeclared

JavaScriptvar john = { “first” : “John”, “last” : “McCarthy”, “greeting” : … };

var twJohn = { “year” : 1971, “__proto__” : john};

twJohn.greeting();

inheritance chaincomputed

Page 32: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

Objects Inherit from Prototypes

var john = { “first” : “John”, “last” : “McCarthy”, “greeting” : … };

var twJohn = { “year” : 1971, “__proto__” : john};

twJohn.greeting();

JavaScript

32

Page 33: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

Objects Inherit from Prototypes

Objects are Extensible

Objects are Dictionaries

Lightweight Reflection

Core Technical Challenges

33

Page 34: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

Refinement Types

Dependent JavaScript

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

C#

✓✓✓✓

✓*✓

✗✗

✗✗✗✗

Java

Haskell

Scala

lightweight reflection

objects are dictionaries

objects are extensible

prototype inheritance

34

Page 35: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

35

OutlineMotivation and Thesis

Challenges of Dynamic LanguagesTour of Dependent JavaScript

Technical ContributionsEvaluation

Looking Ahead

Page 36: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

36

typeof true // “boolean”

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

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

Page 37: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

37

typeof returns run-time “tags”

Tags are very coarse-grained types

“undefined”

“boolean”

“string”

“number”

“object”

“function”

Page 38: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

38

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 39: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

39

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

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

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

{x|true }Any

Syntactic Sugarfor Common Types

Refinement Types

Page 40: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

3 :: {n|n = 3}

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

Refinement Types

40

Page 41: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

{n|n = 3}

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

<:...

Subtyping is Implication

Refinement Types

41

Page 42: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

{n|n = 3}

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

Subtyping is Implication

Refinement Types

42

Page 43: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

Refinement Types

SMT Solveror Theorem

Prover

RefinementType

Checker

p q ?

Yes / No

43

Subtyping is Implication

Page 44: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

44

Mutable ObjectsDictionary ObjectsTag-Tests Prototypes

Page 45: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

45

Mutable ObjectsDictionary ObjectsTag-Tests Prototypes

function negate(x) {

if (typeof x == “number”) {

return 0 - x;

} else {

return !x;

} }

Type Annotation in Comments

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

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

NumOrBool

Syntactic Sugarfor Common Types

Page 46: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

46

Mutable ObjectsDictionary ObjectsTag-Tests Prototypes

function negate(x) {

if (typeof x == “number”) {

return 0 - x;

} else {

return !x;

} }

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

{x|tag(x) = “number” }

“expected args”

{x|tag(x) = “number” }

{x|tag(x) = “number” }

{x|tag(x) = “number” }✓

Page 47: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

47

Mutable ObjectsDictionary ObjectsTag-Tests Prototypes

function negate(x) {

if (typeof x == “number”) {

return 0 - x;

} else {

return !x;

} }

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

“expected args”

{x|tag(x) = “boolean” }

✓{x|not(tag(x) = “number”)

{x| ∧ (tag(x) = “number” ∨

{x| tag(x) = “boolean”) }

Page 48: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

48

Mutable ObjectsDictionary ObjectsTag-Tests Prototypes

function negate(x) {

if (typeof x == “number”) {

return 0 - x;

} else {

return !x;

} }

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

Refinement Types Enable Path Sensitivity

Page 49: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

49

Mutable ObjectsDictionary ObjectsTag-Tests Prototypes

function negate(x) {

if (typeof x == “number”) {

return 0 - x;

} else {

return !x;

} }

Output typedepends on input

value

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

Page 50: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

50

if (“quack” in duck)

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

else

return “This duck can’t quack!”;

What is “Duck Typing”?

Mutable ObjectsTag-Tests Dictionary Objects Prototypes

Page 51: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

51

if (“quack” in duck)

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

else

return “This duck can’t quack!”;

What is “Duck Typing”?

(+) :: (Num,Num) Num

(+) :: (Str,Str) Str

Mutable ObjectsTag-Tests Dictionary Objects Prototypes

Page 52: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

52

if (“quack” in duck)

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

Mutable ObjectsTag-Tests Dictionary Objects Prototypes

Page 53: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

53

if (“quack” in duck)

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

else

return “This duck can’t quack!”;

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

{v|has(d,“quack”)

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

Operators from McCarthy theory of arrays

Mutable ObjectsTag-Tests Dictionary Objects Prototypes

Page 54: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

54

if (“quack” in duck)

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

else

return “This duck can’t quack!”;

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

{v|has(d,“quack”)

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

Call produces Str, so concat well-typed

Mutable ObjectsTag-Tests Dictionary Objects Prototypes

Page 55: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

55

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

Dictionary ObjectsTag-Tests Mutable Objects Prototypes

Page 56: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

56

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

Dictionary ObjectsTag-Tests Mutable Objects Prototypes

Page 57: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

child

parent

...

grandpa

null

Upon construction, each object links to a

prototype object

57

Dictionary ObjectsTag-Tests PrototypesMutable Objects

Page 58: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

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

58

Dictionary ObjectsTag-Tests PrototypesMutable Objects

Page 59: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

...

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)

59

Dictionary ObjectsTag-Tests PrototypesMutable Objects

Page 60: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

...

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)

60

Dictionary ObjectsTag-Tests PrototypesMutable Objects

Page 61: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

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)

child

parent

grandpa ???

null

H(Rest of Heap)

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

61

Dictionary ObjectsTag-Tests PrototypesMutable Objects

Page 62: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

...

{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

62

Dictionary ObjectsTag-Tests PrototypesMutable Objects

Page 63: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

...

{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];

63

Dictionary ObjectsTag-Tests PrototypesMutable Objects

Page 64: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

...

{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”}

64

Dictionary ObjectsTag-Tests PrototypesMutable Objects

Page 65: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

Key Idea:

Reduce prototypesemantics to decidable

theory of arrays

Prototype Chain Unrolling

65

Dictionary ObjectsTag-Tests PrototypesMutable Objects

Page 66: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

“The Good Parts”

reflection

arrays

eval()*

lambdas

JavaScript

66

objects

✓✓

EXTRA SLIDES

Page 67: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

67

OutlineMotivation and Thesis

Challenges of Dynamic LanguagesTour of Dependent JavaScript

Technical ContributionsEvaluation

Looking Ahead

Page 68: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

68

lambdasdictionariestag tests

mutation

prototypes

Translation à la Guha et al. (ECOOP 2010)

Dependent JavaScript (DJS)

Our Strategy:

Build an expressive type system forcore language

Page 69: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

69

lambdasdictionariestag tests

mutation

prototypes

(POPL 2012)

(OOPSLA 2012)

System D

System !D

System DJS (OOPSLA 2012)

Dependent JavaScript (DJS)Dependent JavaScript (DJS)

Page 70: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

70

Prior Refinement Types

TypesT ::= {x:B|p }

| x:T1 T2

| [f1:T1; … ]

| Map[A,B]

| Ref(T)

base type (e.g. Int, Bool, Str)

dependent function type

object type (a.k.a. record, struct)

dictionary type (a.k.a. map, hash table)

reference type (a.k.a. pointer)

Predicates refine only base types

Page 71: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

71

PriorRefinement

Types

C#System DJS

✓✓✓✓

✓*✓

✗✗

✗✗✗✗

Java

Haskell

Scala

lightweight reflection

objects are dictionaries

objects are extensible

prototype inheritance

Page 72: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

72

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

*✓✗✗

objects are dictionaries

objects are extensible

prototype inheritance

✓✓✓

Page 73: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

73

Key Challenge:

Function Subtypingas Logical Implication

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

Page 74: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

74

42 + negate (17)

{f|f :: }(x:Num) Num “expected function”

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

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

Page 75: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

{f|f :: }

75

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

{f|f :: }(x:Num) Num

How to Prove

?How to Encode Type System Inside Logic?

Prior Refinement SystemsDisallow Function Types Inside Logic!

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

Page 76: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

76

T ::= {x|p }

| T1 T2

Types Refinement Logic

Satisfiability Modulo Theories (SMT)

SAT + Decidable Theories

p q✓✗

SMT Solver(e.g. Z3)

[Prior State-of-the-Art]

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

Page 77: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

77

T ::= {x|p }

| T1 T2

p ::= p ∧ q | p ∨ q | p

| x = y | x > y | …

| tag(x) = “number” | …

| sel(x,k) = 17 | …

Types Refinement Logic

• Boolean Connectives• Equality• Linear Arithmetic• Uninterpreted Functions• McCarthy Arrays

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

Page 78: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

78

T ::= {x|p }

| T1 T2

p ::= p ∧ q | p ∨ q | p

| x = y | x > y | …

| tag(x) = “number” | …

| sel(x,k) = 17 | …

Types Refinement Logic

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

Enables Union Types and Lightweight Reflection

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

Page 79: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

79

T ::= {x|p }

| T1 T2

p ::= p ∧ q | p ∨ q | p

| x = y | x > y | …

| tag(x) = “number” | …

| sel(x,k) = 17 | …

Types Refinement Logic

Enables Dictionary Types with Dynamic Keys …{d|tag(sel(d,k)) = “boolean” ∧

{d|tag(sel(d,“f”)) = “function” ∧

{d|sel(d,“f”) ??? }

But DisallowsFunctions inDictionaries!

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

Page 80: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

80

p ::= p ∧ q | p ∨ q | p

| x = y | x > y | …

| tag(x) = “number” | …

| sel(x,k) = 17 | …

| sel(x,k) :: T1 T2 | …

Types Refinement Logic

Goal: Refer to Type System Inside LogicGoal: Without Giving up Decidability

T ::= {x|p }

| T1 T2

Solution: Nested Refinements!

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

Page 81: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

81

T ::= {x|p } p ::= p ∧ q | p ∨ q | p

| x = y | x > y | …

| tag(x) = “number” | …

| sel(x,k) = 17 | …

| sel(x,k) :: T1 T2 | …

Nested Refinements [POPL ’12]1. Decidable Encoding2. Precise Subtyping3. Type Soundness Proof

Types Refinement LogicJavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

Page 82: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

82

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

{f|f :: }(x:Num) Num

Decidable Encoding

Uninterpreted Predicate in Logic

Distinct UninterpretedConstants in Logic…

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

Page 83: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

{f|f :: }

83

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

{f|f :: }(x:Num) Num

Decidable Encoding

Uninterpreted Predicate in Logic

w/ Types Nested Inside

Distinct UninterpretedConstants in Logic…

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

Page 84: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

84

Decidable Encoding

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

{f|f :: }(x:Num) Num

✗SMTSolver

Trivially Decidable, but Imprecise

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

Page 85: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

85

p f :: (x:S1) S2

{f|f :: }(x:T1) T2

{f|p }

Precise Subtyping

Step 1:

Step 2:

Find such that(x:S1) S2

SMTSolver✓

T1 S1 ✓✓S2 T2x:T1

Compare and(x:S1) S2 (x:T1) T2

“contra-variance”

“co-variance”

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

Page 86: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

86

{f|f :: }(x:Num) Num{f|f = negate }

Precise Subtyping

Step 1:

Step 2:

f = negate

f :: (x:NumOrBool) { y|tag(y) = tag(x) }SMTSolver✓

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

Page 87: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

87

{f|f :: }(x:Num) Num{f|f = negate }

Precise Subtyping

Step 1:

Step 2:

f = negate

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

Num

NumOrBool ✓✓{y|tag(y) = tag(x) } Nu

mx:Num

✓SMT

Solver✓

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

Page 88: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

88

Precise Subtyping

Step 1:

Step 2:

Decidable Reasoningvia SMT

Precise Function Subtypingvia Syntactic Techniques

+

{f|f :: }{f|f = negate } ✓(x:Num) Num

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

Page 89: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

89

Type Soundness Proof

Logic 0

Conventional ProofsRequire Logic to be an Oracle …

… but Nesting Introduces CircularityThat Prevents Typical Inductive Proofs

Type System 0

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

Page 90: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

90

Type System ∞

Type Soundness Proof

Logic 0

Logic 1

Logic 2

Type System 1

Type System 2

Type System 0

… …

Proof Technique:Stratify into Infinite Hierarchy

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

Page 91: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

91

Key to Encode Dictionary Objects(Even in Statically Typed Languages!)

T ::= {x|p } p ::= p ∧ q | p ∨ q | p

| x = y | x > y | …

| tag(x) = “number” | …

| sel(x,k) = 17 | …

| sel(x,k) :: T1 T2 | …

Nested Refinements [POPL ’12]

Types Refinement LogicJavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

Page 92: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

92

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

var x = {};

x.f = 7;

x.f + 2;

let x = new {} in

(*x).f = 7;

(*x).f + 2;

Allocates ptr x :: Ref(Dict)

Heap update doesn’t affect type

So key lookup doesn’t type check!

Key Issue:

“Invariant”Reference Types

Page 93: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

93

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

let x = new {} in

(*x).f = 7;

(*x).f + 2;

Lx |-> d0:{d|d =empty}

Lx |-> d1:{d|d = upd(d0,“f”,7)}

Allocates heap location Lx and x :: Ref(Lx)

Type of pointer doesn’t change …

But types of heap locations can!

Page 94: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

94

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

x:T1 / h1 T2 / h2

outputtype

inputtype

Page 95: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

95

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

x:T1 / h1 T2 / h2

outputtype

inputtype

inputheap

outputheap

Page 96: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

96

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

x:T1 / h1 T2 / h2

Our Formulation Extends:

Alias Types (Smith et al., ESOP 2000)syntactic types for higher-order programs

Low-Level Liquid Types (Rondon et al., POPL 2010)refinement types for first-order programs

Page 97: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

97

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

let swap (x, y) =

let tmp = *x in

*x = *y;

*y = tmp in …

//: swap :: (x:Ref(Lx), y:Ref(Ly))

//: / H + (Lx |-> a:Any) + (Ly |-> b:Any)

//: Void//: / H + (Lx |-> a’:Any{a’= b})

//: + (Ly |-> b’:Any{b’= a})

Page 98: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

98

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

//: getKey :: (x:Ref(Lx), k:Str)

//: / H + (Lx |-> d:Dict > Lx’)

//: { y | if has(d,k)//: then y = sel(d, k)//: else y = HeapHas(H, Lx’, k)}

//: / H + (Lx |-> d’:Dict{d’= d} > Lx’)

Prototype Inheritance

x[k] getKey(*x, k)

Page 99: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

99

JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements

Primitive Operators(Avoid Implicit Coercion)

JavaScript Arrays(Several Unusual Issues)

Prototype Inheritance

Page 100: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

100

OutlineMotivation and Thesis

Challenges of Dynamic LanguagesTour of Dependent JavaScript

Technical ContributionsEvaluation

Looking Ahead

Page 101: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

101

313a

421(+35%)

LOCbefore/after

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

Benchmarks

Chosen to Stretch the Limits of DJS

Page 102: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

102

313a

421(+35%)

LOCbefore/after

14 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,637

1,831(+12%)

TOTALS

Page 103: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

103

LOCbefore/after

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

313a

421(+35%)

Benchmarks

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

321a

383(+19%)

2 Examples from: Google Gadgets

1,003a

1,027(+2%)

1,637

1,831(+12%)

11 sec

Running Time

3 sec

19 sec

33 sec

TOTALS

1,831(+12%)

33 sec

>>> Skip Optimizations >>>

Page 104: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

104

Reducing Annotation Burden• Bidirectional (local) type inference– Several aspects unique to this setting

• Optional var declaration invariants– Auto add to types of subsequent closures

var i /*: Int */ = 0;

//: f :: T1 / H1 + (Li |-> i1:Int)

//: T2 / H2 + (Li |-> i2:Int)

var f(…) { … i … }

function refers to mutable variable i, so heaps must describe

the location

Page 105: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

105

Reducing Annotation Burden• Bidirectional (local) type inference– Several aspects unique to this setting

• Optional var declaration invariants– Auto add to types of subsequent closures

var i /*: Int */ = 0;

//: f :: T1 / H1

//: T2 / H2

var f(…) { … i … }

copy the annotation, if any

Page 106: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

106

Reducing Annotation Burden• Bidirectional (local) type inference– Several aspects unique to this setting

• Optional var declaration invariants– Auto add to types of subsequent closures

var i /*: Int */ = 0;

//: f :: T1 / H1 + (Li |-> i1:Int)

//: T2 / H2 + (Li |-> i2:Int)

var f(…) { … i … }

copy the annotation, if any

Page 107: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

107

Reducing Annotation Burden• Bidirectional (local) type inference– Several aspects unique to this setting

• Optional var declaration invariants– Auto add to types of subsequent closures

no annotation means “do not modify”var i = 0;

//: f :: T1 / H1 + (Li |-> i1:{x | x = 0})

//: T2 / H2 + (Li |-> i2:{x | x = 0})

var f(…) { … i … }

Page 108: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

108

Improving Performance

17 :: {x:Int|x = 17 }

if b then “hi” else 17 :: {x|b = true x = “hi”

if b then 17 else “hi” :: {x∧b = false x = 17 }

track syntactic types for specialized cases …

… fall back on refinement types for general case

• Avoid making SMT queries when possible

Page 109: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

109

Improving Performance• Can reduce precision for if-expressions

var n = 0;

if (b) {

n = n + 1;

else {

n = n + 2;

} Ln |-> m:{ x | b = true x = 1Ln |-> m: {x ∧ b = false x = 2 }

“exact joins” by default …

… annotation on var triggers “inexact joins”

Page 110: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

110

Improving Performance• Can reduce precision for if-expressions

var n /*: Int */ = 0;

if (b) {

n = n + 1;

else {

n = n + 2;

}

Ln |-> m:Int

“exact joins” by default …

… annotation on var triggers “inexact joins”

Page 111: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

111

Plenty of Room for Improvement

1,637

TOTALS

33 sec

1,831(+12%)

Relatively Modest OptimizationsHave Made Significant Impact

Page 112: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

112

OutlineMotivation and Thesis

Challenges of Dynamic LanguagesTour of Dependent JavaScript

Technical ContributionsEvaluation

Looking Ahead

Page 113: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

113

Immediate Directions• Type Soundness– proven for System D, but not for !D or DJS

• Expressiveness– e.g. mutual recursion, recursion through heap

• Usability– annotation burden, performance, error messages

• Integration with Run-Time Contracts– invariants before and after eval()

Page 114: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

114

Expressiveness

Usability

Verification

Dependent JavaScript (DJS)

TypeScriptLightweight (unsound) static checking tools becoming popular

Translate for additional checking

and IDE support

“Gradual Gradual Typing”

Page 115: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

115

Way Behind Tools for Java, etc.

• Static Types in DJS Enable Refactoring,• Documentation Tools, Code Completion

• Web-Based Interfaces to Collect Statistics• about Programming Patterns, Errors

Web Development Tools

Page 116: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

116

candidateannotations

User or

Test Cases or

Heuristics

Iterative InferenceGlobal inference (e.g. via Liquid Types) would be nice,but no basic type structure to start with

unannotatedprogram

Verification Condition

Generation

Coarsen Types

Page 117: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

117

Browser Extension Security

Security =Refinement

Type Checkingà la Swamy et al. (ESOP 2010)

and Guha et al. (Oakland 2011)

Dependent JavaScript (DJS)

Third-PartyCode

Policy

Browser APIs

Secure Reference Monitorvia Refinements

Page 118: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

118

Thanks!

Nested Refinements +Dependent JavaScript

Ranjit JhalaPat Rondon

Dave HermanPanos Vekris

OtherProjects

Sorin LernerJan Voung

Jeff MeisterNikhil Swamy

Juan Chen

Page 119: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

119

EXTRA SLIDES

Page 120: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

“The Good Parts”

reflection

arrays

eval()*

lambdas

JavaScript

120

objects

Page 121: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

121

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

A finite tuple…

… extended to unbounded collection

Page 122: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

122

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 123: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

123

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 124: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

124

{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 125: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

125

var tup = [17, “cacti”];

tup[tup.length] = true;

{a |a :: Arr(Any)

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

{a | …}

Page 126: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

“The Good Parts”

reflection

arrays

eval()*

lambdas

JavaScript

126

objects

Page 127: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

127

What About eval?

Arbitrary code loading

eval(“…”);

Old Types

Page 128: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

128

What About eval?

eval(“…”);

//: #assume

Old Types

New TypesNew Types

Future Work: Integrate DJS with“Contract Checking” at Run-time

aka “Gradual Typing”

Page 129: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

129Expressiveness

Usability Idioms ofDynamic Languages

VerificationHoare Logics

Model CheckingAbstract Interpretation

Theorem Proving…

Page 130: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

130

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

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

Higher-Order Refinements

Page 131: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

131

Function Subtyping…

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

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

Higher-Order Refinements

Page 132: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

132

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

Higher-Order Refinements

Page 133: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

133

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

Higher-Order Refinements

Page 134: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

134

Subtyping with Nesting

e.g. tag(x) = tag(y)

e.g. tag(sel(d,k)) = “number”

1) Convert q to CNF clauses (q11 … ) … (qn1 … )

2) For each clause, discharge some literal qij as follows:

base predicate: p qij

anything except HasType(x,U)

Page 135: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

135

Subtyping with Nesting

Implication

SMT Solver

Subtyping Arrow Rule

base predicate: p qij p x :: U

Implication

SMT Solver

Subtyping

p x :: U’

U’ <: U

p qij

1) Convert q to CNF clauses (q11 … ) … (qn1 … )

2) For each clause, discharge some literal qij as follows:

Page 136: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

136

Type Soundness with Nesting

Page 137: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

137

0 :: {|x.x+1:: IntInt }_|

x.x+1 :: {|:: IntInt }_|

f:{|:: IntInt }0 :: {|f:: IntInt }_|

SubstitutionLemma

_| v :: TxandIf x:Tx, Γ e[:: T_|

Γ[v/x] e[v/x] :: T[v/x]_|then

independent of 0, and just echoes the binding from the environment

Page 138: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

138

0 :: {|x.x+1:: IntInt }_|

SMT =0 x.x+1:: IntInt✗{|=0 } < {|x.x+1:: IntInt }0 :: {|=0 }

SubstitutionLemma

_| v :: TxandIf x:Tx, Γ e[:: T_|

Γ[v/x] e[v/x] :: T[v/x]_|then

1st attempt

Page 139: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

139

0 :: {|x.x+1:: IntInt }_|

{|=0 } < {|x.x+1:: IntInt }0 :: {|=0 }

SubstitutionLemma

_| v :: TxandIf x:Tx, Γ e[:: T_|

Γ[v/x] e[v/x] :: T[v/x]_|then✗SMT =0 :: U’

Arrow U’ <: IntInt

+2nd attempt✗

Page 140: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

140

x.x+1:: IntInt|=I

x.x+1:: {|:: IntInt }|_

SMT Γ p q

Γ {|=p } < {|=q }_|

[S-Valid-Uninterpreted]

|=I Γ p q

Γ {|=p } < {|=q }_|

[S-Valid-Interpreted]

iff

• Rule not closed under substitution

• Interpret formulas by “hooking back” into type system

• Stratification to create ordering for induction

n

n-1

n

n

Page 141: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

141

Type Soundness with NestingStratifiedSubstitutionLemma

_| v :: TxandIf x:Tx, Γ e[:: T_|

Γ[v/x] e[v/x] :: T[v/x]_|then n+1

n

n

StratifiedPreservation

e vandIf e[:: T_| 0

_|then v[:: Tm for some m

“Level 0” for type checking source programs,using only [S-Valid-Uninterpreted]

artifact of the metatheory

Page 142: Nested Refinement Types for JavaScript Ravi Chugh Dissertation Defense − September 3, 2013

142

</Ph.D.>