Ben Greenman Matthias Felleisen Christos Dimoulas at at at COMPLETE MONITORS FOR GRADUAL TYPES
Ben Greenman Matthias Felleisen Christos Dimoulas at at at COMPLETE MONITORS FOR GRADUAL TYPES a careful analysis of the mixed-typed design space
Type soundness is not enough Complete monitoring is crucial for meaningful gradual types "Incomplete" monitoring provides a way to measure the quality of blame errors *from ESOP 2012 *
Mixed-Typed Language
Untyped/Typed mix Mixed-Typed Language = untyped code = simply-typed (no 'Dynamic' type) code U U U T T T U
A Few Motivations U U T T U
Prototyping A Few Motivations U U T T U
Prototyping A Few Motivations write untyped code, rely on types U U T T U
Prototyping A Few Motivations write untyped code, rely on types Re-Use U U T T U
Prototyping A Few Motivations write untyped code, rely on types Re-Use write typed code, use old libraries U U T T U
Many Implementations ... Python TypeScript JavaScript + Hack PHP + Mypy + JavaScript Reticulated Python + Typed Racket Racket + Flow +
Many Implementations ... JavaScript ... diffcult to compare + TypeScript JavaScript + Hack PHP + Mypy Python + Reticulated Python + Typed Racket Racket + Flow UTU U T
Many Models, too GTLC AGT λH λ* → UTU U T
Goal: Characterize the Landscape
Non-Goal : Restrict Landscape
Warmup: Optional Typing / Erasure
Example: Optional Typing T function f (x : [N,N]) { ... fst x ... }
Example: Optional Typing T U function f (x : [N,N]) { f(9) ... fst x ... }
Example: Optional Typing T U function f (x : [N,N]) { f(9) ... fst x ... } Error: 9 is not a pair
types are meaningless at run-time Example: Optional Typing cannot help debug a faulty program T U function f (x : [N,N]) { f(9) ... fst x ... } Error: 9 is not a pair
= Does Not Preserve Types Uni sound
= Does Not Preserve Types Uni sound "type" sound
ICFP '18
ICFP '18 : Three Semantics, Soundnesses
ICFP '18 : Three Semantics, Soundnesses Erasure semantics - types predict nothing
ICFP '18 : Three Semantics, Soundnesses Erasure semantics - types predict nothing Transient semantics - types predict the top-level shape of values - enforced by tag checks
ICFP '18 : Three Semantics, Soundnesses Erasure semantics - types predict nothing Transient semantics - types predict the top-level shape of values - enforced by tag checks Natural semantics - types predict the full behavior of values - enforced by higher-order wrappers
ICFP '18 : Three Semantics, Soundnesses T sound - types predict the full behavior of values Natural semantics - enforced by tag checks - types predict the top-level shape of values Transient semantics - types predict nothing Erasure semantics - enforced by higher-order wrappers Erasure semantics Uni sound - enforced by higher-order wrappers - types predict the full behavior of values Natural semantics - enforced by tag checks - types predict the top-level shape of values Transient semantics - types predict nothing ⌊ T ⌋ sound
ICFP '18: A Spectrum of Type Soundness Uni sound
ICFP '18: A Spectrum of Type Soundness Uni sound Uni sound T sound Erasure Natural Transient ⌊ T ⌋ sound
Natural T sound Transient ⌊ T ⌋ sound
- enforced by higher-order wrappers T sound - types predict the full behavior of values Natural semantics - enforced by tag checks - types predict the top-level shape of values Transient semantics T sound - enforced by higher-order wrappers - types predict the full behavior of values Natural semantics - enforced by tag checks - types predict the top-level shape of values Transient semantics Transient Natural ⌊ T ⌋ sound ⌊ T ⌋ sound
Natural T sound Transient ⌊ T ⌋ sound
T sound Natural Transient Amnesic Amnesic semantics with higher-order wrappers - same behavior as Transient - same type soundness as Natural OOPSLA '19 Greenberg POPL '15 Castagna, Lanvin ICFP '17 ⌊ T ⌋ sound - enforce tag checks ⌊ T ⌋
Type Soundness is NOT ENOUGH Uni sound T sound ??? Erasure Natural Transient Amnesic ⌊ T ⌋ sound
Example: Transient/Amnesic vs. Natural
Example: Transient/Amnesic vs. Natural Prototyping
Example: Transient/Amnesic vs. Natural Prototyping Library Re-Use
Example: Transient/Amnesic vs. Natural Prototyping Library Re-Use Combine: untyped script + typed API + untyped library via a higher-order value
Example: Transient/Amnesic vs. Natural 1. plot data 2. listen for a click 3. draw an image Clickable Plot 1
Example: Transient/Amnesic vs. Natural 1. plot data 2. listen for a click 3. draw an image Clickable Plot 2
Example: Transient/Amnesic vs. Natural 1. plot data 2. listen for a click 3. draw an image Clickable Plot 3
Example: interactive plot Client Library API U T U
Example: interactive plot Client API Library U T U function h(x) { if (0 < fst x): pumpkin else : fish } p = ClickPlot(h) p.show() // click
Example: interactive plot Client API Library U T U function h(x) { class ClickPlot { if (0 < fst x): constructor ( pumpkin onClick){...} else : fish mouseHandler(evt){ } i = onClick(evt) // draw i p = ClickPlot(h) } p.show() show(){...} // click }
Example: interactive plot Library Client API U T U function h(x) { type ClickPlot { class ClickPlot { if (0 < fst x): constructor ( constructor ( pumpkin ([N,N]) => Image) onClick){...} else : fish mouseHandler : mouseHandler(evt){ } (MouseEvt) => Void i = onClick(evt) // draw i p = ClickPlot(h) } p.show() show : () => Void show(){...} // click } }
Example: interactive plot Library Client API U T U function h(x) { type ClickPlot { class ClickPlot { if (0 < fst x): constructor ( constructor ( pumpkin ([N,N]) => Image) onClick){...} else : fish mouseHandler : mouseHandler(evt){ } (MouseEvt) => Void i = onClick(evt) // draw i p = ClickPlot(h) } p.show() show : () => Void show(){...} // click } }
Example: interactive plot Library Client API Promises a pair of numbers U T U function h(x) { type ClickPlot { class ClickPlot { if (0 < fst x): constructor ( constructor ( pumpkin ([N,N]) => Image) onClick){...} else : fish mouseHandler : mouseHandler(evt){ } (MouseEvt) => Void i = onClick(evt) // draw i p = ClickPlot(h) } p.show() show : () => Void show(){...} // click } }
Example: interactive plot Library Client API Promises a pair of numbers U T U function h(x) { type ClickPlot { class ClickPlot { if (0 < fst x): constructor ( constructor ( pumpkin ([N,N]) => Image) onClick){...} else : fish mouseHandler : mouseHandler(evt){ } (MouseEvt) => Void i = onClick(evt) // draw i p = ClickPlot(h) } p.show() show : () => Void show(){...} // click } }
Example: interactive plot Library Promises a pair of numbers Client API Expects a pair of numbers U T U function h(x) { type ClickPlot { class ClickPlot { if (0 < fst x): constructor ( constructor ( pumpkin ([N,N]) => Image) onClick){...} else : fish mouseHandler : mouseHandler(evt){ } (MouseEvt) => Void i = onClick(evt) // draw i p = ClickPlot(h) } p.show() show : () => Void show(){...} // click } }
Example: interactive plot Library Client API U T U function h(x) { type ClickPlot { class ClickPlot { if (0 < fst x): constructor ( constructor ( pumpkin ([N,N]) => Image) onClick){...} else : fish mouseHandler : mouseHandler(evt){ } (MouseEvt) => Void i = onClick(evt) // draw i p = ClickPlot(h) } p.show() show : () => Void show(){...} // click } }
Example: interactive plot Library Client API U T U function h(x) { type ClickPlot { class ClickPlot { if (0 < fst x): constructor ( constructor ( pumpkin ([N,N]) => Image) onClick){...} else : fish mouseHandler : mouseHandler(evt){ } (MouseEvt) => Void i = onClick(evt) // draw i p = ClickPlot(h) } p.show() show : () => Void show(){...} // click } }
Example: interactive plot Client Library API U T U function h(x) { type ClickPlot { class ClickPlot { if (0 < fst x): constructor ( constructor ( pumpkin ([N,N]) => Image) onClick){...} else : fish mouseHandler : mouseHandler(evt){ } (MouseEvt) => Void i = onClick(evt) // draw i Sends MouseEvt value p = ClickPlot(h) } p.show() show : () => Void show(){...} // click } }
Example: interactive plot Client Library API U T U function h(x) { type ClickPlot { class ClickPlot { if (0 < fst x): constructor ( constructor ( pumpkin ([N,N]) => Image) onClick){...} else : [N,N] != MouseEvt fish mouseHandler : mouseHandler(evt){ } (MouseEvt) => Void i = onClick(evt) // draw i Sends MouseEvt value p = ClickPlot(h) } p.show() show : () => Void show(){...} // click } }
Recommend
More recommend