nested refinement types for javascript
DESCRIPTION
Dissertation Defense − September 3, 2013. Nested Refinement Types for JavaScript. Ravi Chugh. “Dynamic” or Untyped Fatures Enable Rapid Prototyping. Types for JavaScript. “Dynamic” or Untyped Fatures Enable Rapid Prototyping. Types for JavaScript. http://stackoverflow.com/tags 02-03-13. - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/1.jpg)
Nested RefinementTypes for JavaScript
Ravi Chugh
Dissertation Defense − September 3, 2013
![Page 2: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/2.jpg)
Types for JavaScript
“Dynamic” or UntypedFatures Enable
Rapid Prototyping
2
![Page 3: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/3.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/4.jpg)
Types for JavaScript
“Dynamic” or UntypedFatures Enable
Rapid Prototyping
1. Development Tools2. Reliability & Security
3. Performance
4
![Page 5: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/5.jpg)
5
1. Development Tools
optional “type systems”unsound but provide
some IDE support
![Page 6: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/6.jpg)
6
2. Reliability & Securitylightweight static checkers
run-time invariant checkers
secure language subsets
![Page 7: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/7.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/8.jpg)
8
Types for JavaScript
Why So Hard?
![Page 9: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/9.jpg)
9
implicit global object
scope manipulationJavaScript
var lifting
‘,,,’ == new Array(4)
![Page 10: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/10.jpg)
“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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/11.jpg)
“The Good Parts”
objects
reflection
arrays
eval()*
lambdas
JavaScript
11
![Page 12: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/12.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/13.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/14.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/15.jpg)
15
OutlineMotivation and Thesis
Challenges of Dynamic LanguagesTour of Dependent JavaScript
Technical ContributionsEvaluation
Looking Ahead
![Page 16: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/16.jpg)
“The Good Parts”
objects
reflection
arrays
eval()*
lambdas
JavaScript
16
![Page 17: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/17.jpg)
Core Technical Challenges
reflection
17
objects
![Page 18: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/18.jpg)
Core Technical Challenges
JavaJavaScript
vs.
18
![Page 19: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/19.jpg)
JavaScriptfunction negate(x) { if (typeof x == “number”) { return 0 - x; } else { return !x;} }
run-timetype-test
19
![Page 20: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/20.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/21.jpg)
JavaScriptfunction negate(x) { if (typeof x == “number”) { return 0 - x; } else { return !x;} }
Java
✗21
![Page 22: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/22.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/23.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/24.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/25.jpg)
JavaScriptfunction negate(x) { if (typeof x == “number”) { … } else { …} }
Lightweight Reflection
25
ad-hoc union type
![Page 26: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/26.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/27.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/28.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/29.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/30.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/31.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/32.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/33.jpg)
Objects Inherit from Prototypes
Objects are Extensible
Objects are Dictionaries
Lightweight Reflection
Core Technical Challenges
33
![Page 34: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/34.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/35.jpg)
35
OutlineMotivation and Thesis
Challenges of Dynamic LanguagesTour of Dependent JavaScript
Technical ContributionsEvaluation
Looking Ahead
![Page 36: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/36.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/37.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/38.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/39.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/40.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/41.jpg)
{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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/42.jpg)
{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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/43.jpg)
Refinement Types
SMT Solveror Theorem
Prover
RefinementType
Checker
pq ?
Yes / No
43
Subtyping is Implication
![Page 44: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/44.jpg)
44
Mutable ObjectsDictionary ObjectsTag-Tests Prototypes
![Page 45: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/45.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/46.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/47.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/48.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/49.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/50.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/51.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/52.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/53.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/54.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/55.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/56.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/57.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/58.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/59.jpg)
...
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/60.jpg)
...
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/61.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/62.jpg)
...
{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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/63.jpg)
...
{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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/64.jpg)
...
{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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/65.jpg)
Key Idea:Reduce prototype
semantics to decidable theory of arrays
Prototype Chain Unrolling
65
Dictionary ObjectsTag-Tests PrototypesMutable Objects
![Page 66: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/66.jpg)
“The Good Parts”
reflection
arrays
eval()*
lambdas
JavaScript
66
objects
✓✓
✓
EXTRA SLIDES
![Page 67: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/67.jpg)
67
OutlineMotivation and Thesis
Challenges of Dynamic LanguagesTour of Dependent JavaScript
Technical ContributionsEvaluation
Looking Ahead
![Page 68: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/68.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/69.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/70.jpg)
70
Prior Refinement Types
TypesT ::= {x:B|p} | x:T1T2
| [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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/71.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/72.jpg)
72
JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements
*✓✗✗
objects are dictionaries
objects are extensible
prototype inheritance
✓✓✓
![Page 73: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/73.jpg)
73
Key Challenge:
Function Subtypingas Logical Implication
JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements
![Page 74: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/74.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/75.jpg)
{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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/76.jpg)
76
T ::= {x|p} | T1T2
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/77.jpg)
77
T ::= {x|p} | T1T2
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/78.jpg)
78
T ::= {x|p} | T1T2
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/79.jpg)
79
T ::= {x|p} | T1T2
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/80.jpg)
80
p ::= p∧q | p∨q | p | x=y | x>y | … | tag(x)=“number” | … | sel(x,k)=17 | … | sel(x,k)::T1T2 | …
Types Refinement Logic
Goal: Refer to Type System Inside LogicGoal: Without Giving up Decidability
T ::= {x|p} | T1T2
Solution: Nested Refinements!
JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements
![Page 81: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/81.jpg)
81
T ::= {x|p} p ::= p∧q | p∨q | p | x=y | x>y | … | tag(x)=“number” | … | sel(x,k)=17 | … | sel(x,k)::T1T2 | …
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/82.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/83.jpg)
{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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/84.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/85.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/86.jpg)
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)}SMT
Solver✓
JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements
![Page 87: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/87.jpg)
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)} Numx:Num
✓SMT
Solver✓
JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements
![Page 88: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/88.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/89.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/90.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/91.jpg)
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)::T1T2 | …
Nested Refinements [POPL ’12]
Types Refinement LogicJavaScript EncodingsFlow-Sensitive RefinementsNested Refinements
![Page 92: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/92.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/93.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/94.jpg)
94
JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements
x:T1/h1T2/h2
outputtype
inputtype
![Page 95: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/95.jpg)
95
JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements
x:T1/h1T2/h2
outputtype
inputtype
inputheap
outputheap
![Page 96: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/96.jpg)
96
JavaScript EncodingsFlow-Sensitive RefinementsNested Refinements
x:T1/h1T2/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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/97.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/98.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/99.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/100.jpg)
100
OutlineMotivation and Thesis
Challenges of Dynamic LanguagesTour of Dependent JavaScript
Technical ContributionsEvaluation
Looking Ahead
![Page 101: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/101.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/102.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/103.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/104.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/105.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/106.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/107.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/108.jpg)
108
Improving Performance
17 :: {x:Int|x=17}
ifbthen“hi”else17 :: {x|b=true x=“hi”ifbthen17else“hi” :: {x∧b=falsex=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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/109.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/110.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/111.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/112.jpg)
112
OutlineMotivation and Thesis
Challenges of Dynamic LanguagesTour of Dependent JavaScript
Technical ContributionsEvaluation
Looking Ahead
![Page 113: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/113.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/114.jpg)
114Expressiveness
Usability
Verification
Dependent JavaScript (DJS)
TypeScript Lightweight (unsound) static checking tools becoming popular
Translate for additional checking
and IDE support
“Gradual Gradual Typing”
![Page 115: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/115.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/116.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/117.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/118.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/119.jpg)
119
EXTRA SLIDES
![Page 120: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/120.jpg)
“The Good Parts”
reflection
arrays
eval()*
lambdas
JavaScript
120
objects
![Page 121: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/121.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/122.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/123.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/124.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/125.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/126.jpg)
“The Good Parts”
reflection
arrays
eval()*
lambdas
JavaScript
126
objects
![Page 127: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/127.jpg)
127
What About eval?
Arbitrary code loading
…
eval(“…”); …
Old Types
![Page 128: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/128.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/129.jpg)
129Expressiveness
Usability Idioms ofDynamic Languages
VerificationHoare Logics
Model CheckingAbstract Interpretation
Theorem Proving…
![Page 130: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/130.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/131.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/132.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/133.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/134.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/135.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/136.jpg)
136
Type Soundness with Nesting
![Page 137: Nested Refinement Types for JavaScript](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/137.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/138.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/139.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/140.jpg)
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/141.jpg)
141
Type Soundness with NestingStratifiedSubstitutionLemma
_| v :: TxandIf x:Tx,Γ e[:: T_|
Γ[v/x] e[v/x] :: T[v/x]_|then n+1
nn
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](https://reader035.vdocuments.net/reader035/viewer/2022062315/56816335550346895dd3c082/html5/thumbnails/142.jpg)
142
</Ph.D.>