1 / 90

Dependent Types for JavaScript

Dependent Types for JavaScript. Ravi Chugh Ranjit Jhala. University of California, San Diego. David Herman. Mozilla Research. Dependent Types for JavaScript. Why. ?. Pervasive Used at Massive Scale. Why Add Types?. var x = {}; x.f ; x.f.f ;.

pravat
Télécharger la présentation

Dependent Types for JavaScript

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. DependentTypes for JavaScript Ravi ChughRanjitJhala University of California, San Diego David Herman Mozilla Research

  2. DependentTypes for JavaScript Why ? Pervasive Used at Massive Scale

  3. Why Add Types? var x = {}; x.f; x.f.f; produces undefined rather than error… … but this raises TypeError

  4. Why Add Types? var x = {}; x.f; x.f.f; There Are Run-time Errorsreading from undefined, applying non-function values, … Worse: Browsers Hide Them!

  5. Why Add Types? Prevent Errors Prevent the Unexpected

  6. Okay, But Who Cares? ProgrammersJSLint, Closure Compiler, TypeScript, Dart Browser VendorsCompete based on performance, security, reliability Standards CommitteesActively evolving JavaScript and Web standards

  7. DependentTypes for JavaScript Why ? Isn’t the Language Terrible?

  8. JavaScript scope manipulation implicit global object var lifting ‘,,,’ == new Array(4)

  9. JavaScript scope manipulation prototypes objects implicit global object lambdas type-tests var lifting ‘,,,’ == new Array(4)

  10. JavaScript scope manipulation “The Good Parts” prototypes objects implicit global object lambdas type-tests var lifting ‘,,,’ == new Array(4)

  11. JavaScript “The Good Parts” Our Approach Key Idea: Use Logic! PriorTypeSystems

  12. JavaScript “The Good Parts” DJS Dependent JavaScript

  13. Outline • Motivation • Our Approach: Logic! • Evaluation

  14. typeof true // “boolean” typeof 0.1 // “number”typeof 0 // “number” typeof {}// “object”typeof []// “object”typeof null// “object”

  15. typeof returns run-time “tags” Tags are very coarse-grained types “undefined” • “boolean” • “string” • “number” • “object” • “function”

  16. Refinement Types NumOrBool  {x|p} Num Int Any  {v|tag(v)=“number”∨tag(v)=“boolean”} {n|tag(n)=“number”} {i|tag(i)=“number”integer(i)} {x|true} “set of values x s.t. formula p is true”

  17. Refinement Types NumOrBool  Num Int Any  {v|tag(v)=“number”∨tag(v)=“boolean”} {n|tag(n)=“number”} {i|tag(i)=“number”integer(i)} {x|true} • Syntactic Sugarfor Common Types

  18. Refinement Types 3:: {n|n=3} 3:: {n|n>0} 3:: {n|tag(n)=“number”integer(n)} 3:: {n|tag(n)=“number”}

  19. Refinement Types • Subtyping is Implication <: {n|n=3} <: {n|n>0} <: {n|tag(n)=“number”integer(n)} <: {n|tag(n)=“number”}

  20. Refinement Types • Subtyping is Implication  {n|n=3}  {n|n>0}  {n|tag(n)=“number”integer(n)}  {n|tag(n)=“number”}

  21. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays

  22. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays varnegate = function(x) { if (typeofx==“boolean”) return !x; else return0 - x; } !true // false true negate()

  23. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays varnegate = function(x) { if (typeofx==“boolean”) return !x; else return0 - x; } 0 - 2 // -2 2 negate()

  24. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays varnegate = function(x) { if (typeofx==“boolean”) return !x; else return0 - x; } • WAT?! 0 - [] // 0 [] negate()

  25. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays varnegate = function(x) { if (typeofx==“boolean”) return !x; else return0 - x; } • Use types to prevent implicit coercion (-) :: (Num,Num)Num

  26. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays //: negate :: (x:Any)Any varnegate = function(x) { if (typeofx==“boolean”) return !x; else return0 - x; } • Function type annotation inside comments

  27. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays //: negate :: (x:Any)Any varnegate = function(x) { if (typeofx==“boolean”) return !x; else return0 - x; } ✓ x is boolean... so negationis well-typed • DJS is Path Sensitive

  28. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays ✗ //: negate :: (x:Any)Any varnegate = function(x) { if (typeofx==“boolean”) return !x; else return0 - x; } x is arbitrarynon-boolean value… ✗ so DJS signals error! • DJS is Path Sensitive

  29. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays //: negate :: (x:NumOrBool)Any varnegate = function(x) { if (typeofx==“boolean”) return !x; else return0 - x; } ✓

  30. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays //: negate :: (x:NumOrBool)Any varnegate = function(x) { if (typeofx==“boolean”) return !x; else return0 - x; } ✓ • this time,x is a number… so subtractionis well-typed

  31. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays ✓ //: negate :: (x:NumOrBool)Any varnegate = function(x) { if (typeofx==“boolean”) return !x; else return0 - x; } • but returntype is imprecise

  32. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays ✓ //: negate :: (x:NumOrBool)NumOrBool varnegate = function(x) { if (typeofx==“boolean”) return !x; else return0 - x; }

  33. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays /*: negate :: (x:NumOrBool){v|tag(v)=tag(x)} */ ✓ varnegate = function(x) { if (typeofx==“boolean”) return !x; else return0 - x; } • output type depends on input value

  34. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays /*: negate :: (x:NumOrBool){v|tag(v)=tag(x)} */ Programmer choosesdegree of precisionin specification

  35. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays What is “Duck Typing”? if (duck.quack) return“Duck says ” + duck.quack(); else return“This duck can’t quack!”;

  36. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays What is “Duck Typing”? (+) :: (Num,Num)Num (+) :: (Str,Str)Str if (duck.quack) return“Duck says ” + duck.quack(); else return“This duck can’t quack!”;

  37. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays What is “Duck Typing”? • Can dynamically testthe presence of a methodbut not its type if (duck.quack) return“Duck says ” + duck.quack(); else return“This duck can’t quack!”;

  38. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays {d|tag(d)=“Dict”∧ {v|has(d,“quack”)  {v|sel(d,“quack”)::UnitStr} • Operators from McCarthy theory of arrays if (duck.quack) return“Duck says ” + duck.quack(); else return“This duck can’t quack!”;

  39. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays {d|tag(d)=“Dict”∧ {v|has(d,“quack”)  {v|sel(d,“quack”)::UnitStr} • Call produces Str, so concat well-typed ✓ if (duck.quack) return“Duck says ” + duck.quack(); else return“This duck can’t quack!”;

  40. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays • DJS is FlowSensitive x1:{d|d=upd(x0,“f”,7)} x0:Empty var x = {}; x.f = 7; x.f + 2; • McCarthy operator • DJS verifies that x.f is definitely a number

  41. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays • DJS is FlowSensitive x1:{d|d=upd(x0,“f”,7)} x0:Empty var x = {}; x.f = 7; x.f + 2; Strong updates to singleton objects Weak updates to collections of objects

  42. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays

  43. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays • Typical“Dynamic” • Features

  44. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays • Typical“Dynamic” • Features • JavaScript • tl;dr • Harder, butDJS handles them

  45. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays child • Upon construction, each object links to a prototype object parent grandpa ... null

  46. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays • Semantics of Key Lookup var k = “first”; child[k]; child 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 parent grandpa ... null

  47. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays • Semantics of Key Lookup var k = “first”; child[k]; child 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|ifhas(child,k) then {v|ifv=sel(child,k) parent grandpa H(Rest of Heap) ... null

  48. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays • Semantics of Key Lookup var k = “first”; child[k]; child 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|ifhas(child,k) then {v|ifv=sel(child,k) {v|else ifhas(parent,k) then {v|ifv=sel(parent,k) parent grandpa H(Rest of Heap) ... null

  49. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays • Semantics of Key Lookup var k = “first”; child[k]; child 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|ifhas(child,k) then {v|ifv=sel(child,k) {v|else ifhas(parent,k) then {v|ifv=sel(parent,k) parent grandpa ??? H(Rest of Heap) ... null

  50. Tag-Tests • Duck Typing • Mutable Objects • Prototypes • Arrays • Semantics of Key Lookup var k = “first”; child[k]; child {v|ifhas(child,k) then {v|ifv=sel(child,k) {v|else ifhas(parent,k) then {v|ifv=sel(parent,k) {v|else {v|ifv=HeapSel(H,grandpa,k))} parent grandpa ??? • Abstract predicateto summarize theunknown portionof the prototype chain H(Rest of Heap) ... null

More Related