Safe & Efficient Gradual Typing for TypeScript Aseem Rastogi University of Maryland, College Park Nikhil Swamy Cédric Fournet Gavin Bierman Panagiotis.

Slides:



Advertisements
Similar presentations
Sml2java a source to source translator Justin Koser, Haakon Larsen, Jeffrey Vaughan PLI 2003 DP-COOL.
Advertisements

Optional Static Typing Guido van Rossum (with Paul Prescod, Greg Stein, and the types-SIG)
Modular and Verified Automatic Program Repair Francesco Logozzo, Thomas Ball RiSE - Microsoft Research Redmond.
An Abstract Interpretation Framework for Refactoring P. Cousot, NYU, ENS, CNRS, INRIA R. Cousot, ENS, CNRS, INRIA F. Logozzo, M. Barnett, Microsoft Research.
- Vasvi Kakkad.  Formal -  Tool for mathematical analysis of language  Method for precisely designing language  Well formed model for describing and.
Safe TypeScript Aseem Rastogi University of Maryland, College Park
Current Techniques in Language-based Security David Walker COS 597B With slides stolen from: Steve Zdancewic University of Pennsylvania.
1 Mooly Sagiv and Greta Yorsh School of Computer Science Tel-Aviv University Modern Compiler Design.
Dynamic Typing COS 441 Princeton University Fall 2004.
Generic programming in Java
Java Generics.
Alias Annotations for Program Understanding Jonathan Aldrich Valentin Kostadinov Craig Chambers University of Washington.
Data Abstraction COS 441 Princeton University Fall 2004.
Parametric Polymorphism COS 441 Princeton University Fall 2004.
Java Generics. 2 The Dark Ages: Before Java 5 Java relied only on inclusion polymorphism  A polymorphism code = Using a common superclass Every class.
Advanced Object-Oriented Programming Features
OOP #10: Correctness Fritz Henglein. Wrap-up: Types A type is a collection of objects with common behavior (operations and properties). (Abstract) types.
Michael Ernst, page 1 Improving Test Suites via Operational Abstraction Michael Ernst MIT Lab for Computer Science Joint.
1 A Short Introduction to (Object-Oriented) Type Systems Kris De Volder.
Type Inference: CIS Seminar, 11/3/2009 Type inference: Inside the Type Checker. A presentation by: Daniel Tuck.
Inheritance and Polymorphism CS351 – Programming Paradigms.
Taming the Wildcards: Combining Definition- and Use-Site Variance – Altidor John Altidor Taming the Wildcards: Combining Definition- and Use-Site Variance.
CSE341: Programming Languages Lecture 11 Type Inference Dan Grossman Winter 2013.
Modern Concurrency Abstractions for C# by Nick Benton, Luca Cardelli & C´EDRIC FOURNET Microsoft Research.
Imperative Programming
GRADUAL TYPING EMBEDDED SECURELY IN JAVASCRIPT Aseem Rastogi University of Maryland, College Park Joint Work With: Nikhil Swamy, Cédric Fournet, Karthikeyan.
University of Maryland Bug Driven Bug Finding Chadd Williams.
Types for Programs and Proofs Lecture 1. What are types? int, float, char, …, arrays types of procedures, functions, references, records, objects,...
Mathematical Modeling and Formal Specification Languages CIS 376 Bruce R. Maxim UM-Dearborn.
Object Oriented Programming Elhanan Borenstein Lecture #4.
Programming Languages and Design Lecture 7 Subroutines and Control Abstraction Instructor: Li Ma Department of Computer Science Texas Southern University,
March 12, ICE 1341 – Programming Languages (Lecture #6) In-Young Ko Programming Languages (ICE 1341) Lecture #6 Programming Languages (ICE 1341)
Features of Object Oriented Programming Lec.4. ABSTRACTION AND ENCAPSULATION Computer programs can be very complex, perhaps the most complicated artifact.
Testing. 2 Overview Testing and debugging are important activities in software development. Techniques and tools are introduced. Material borrowed here.
Introduction to TypeScript Sergey Barskiy Architect Level: Introductory.
Slide: 1 Copyright © AdaCore Subprograms Presented by Quentin Ochem university.adacore.com.
Encapsulation COMP 401, Fall 2014 Lecture 06 9/4/2014.
Object Oriented Software Development
Hack for HHVM Converting Facebook Julien Verlaguet Software Engineer.
Inheritance Revisited Other Issues. Multiple Inheritance Also called combination--not permitted in Java, but is used in C++ Also called combination--not.
Object vs Class composition By Marine Ruhamanya. Disciplined Inheritance  Problems with implementation inheritance: Encapsulation Fragile Base Class.
How to execute Program structure Variables name, keywords, binding, scope, lifetime Data types – type system – primitives, strings, arrays, hashes – pointers/references.
1 Lecture 17 Static Types type safety, static vs dynamic checks, subtyping Ras Bodik Ali and Mangpo Hack Your Language! CS164: Introduction to Programming.
CSCI-383 Object-Oriented Programming & Design Lecture 24.
Java How to Program, 9/e © Copyright by Pearson Education, Inc. All Rights Reserved.
CMSC 202 Polymorphism. 10/20102 Topics Binding (early and late) Upcasting and downcasting Extensibility The final modifier with  methods  classes.
Soundness of Types Ensuring that a type system is not broken.
Zach Tatlock / Winter 2016 CSE 331 Software Design and Implementation Lecture 13 Generics 1.
The Ins and Outs of Gradual Type Inference Avik Chaudhuri Basil Hosmer Adobe Systems Aseem Rastogi Stony Brook University.
ECE 750 Topic 8 Meta-programming languages, systems, and applications Automatic Program Specialization for J ava – U. P. Schultz, J. L. Lawall, C. Consel.
(C) 2010 Pearson Education, Inc. All rights reserved. Java How to Program, 8/e.
CSC 520 – Advanced Object Oriented Programming, Fall, 2010 Thursday, September 30 Week 5, Generics and Inheritance Techniques, Meyer Ch. 10 & 16.
OOP Tirgul 10. What We’ll Be Seeing Today  Generics – A Reminder  Type Safety  Bounded Type Parameters  Generic Methods  Generics and Inner Classes.
Heath Carroll Bill Hanczaryk Rich Porter.  A Theory of Type Polymorphism in Programming ◦ Robin Milner (1977)  Milner credited with introducing the.
Jeremy Nimmer, page 1 Automatic Generation of Program Specifications Jeremy Nimmer MIT Lab for Computer Science Joint work with.
Polymorphism in Methods
CSE341: Programming Languages Lecture 11 Type Inference
Types for Programs and Proofs
Context-Sensitive Analysis
Matching Logic An Alternative to Hoare/Floyd Logic
Component Based Software Engineering
JavaScript an introduction.
Names, Binding, and Scope
User-Oriented Language Design
TS*: Taming the Un-typed Adversary in JavaScript
CSE341: Programming Languages Lecture 11 Type Inference
CSE341: Programming Languages Lecture 11 Type Inference
CSE341: Programming Languages Lecture 11 Type Inference
CSE341: Programming Languages Lecture 11 Type Inference
CSE341: Programming Languages Lecture 11 Type Inference
Presentation transcript:

Safe & Efficient Gradual Typing for TypeScript Aseem Rastogi University of Maryland, College Park Nikhil Swamy Cédric Fournet Gavin Bierman Panagiotis Vekris (Microsoft Research) (Oracle) (UCSD)

Gradual Typing Combines benefits of static and dynamic typing 2 Statically-typed fragment Dynamically- typed fragment Dynamic type any Runtime checks mediate interaction Static type errors Performance Typed interface documentation Rapid prototyping Flexibility

TypeScript, Dart, Closure, Flow (we focus on TypeScript) Increase programmer productivity (static type errors, intellisense, code refactoring, modularity …) Types don’t get in the way of good programmers (retain flavor of programming in JavaScript) 3 Increasing Adoption in Industry Mainly for JavaScript

TypeScript is Intentionally Unsound For All Its Dynamic Idioms, Typing JavaScript is Hard ! Unsound typing rules to support supposedly common idioms (covariant array subtyping, covariant function arguments, …) Types are uniformly erased during compilation (lightweight compilation, no runtime performance cost, …) (unchecked runtime casts, types don’t guarantee anything) 4

Programmers Cannot Rely On Types 5 private parseColorCode (c:string) { if (typeof c !== "string") return -1; … } Snippet from TouchDevelop, a large TypeScript Development Tools can’t rely on types Refactoring, compiler optimizations, etc. are not safe

6 Can we design a gradual type system that is: Safe Efficient Supports idiomatic TypeScript/JavaScript We present Safe TypeScript

Safe TypeScript is Sound TypeScript is Intentionally Unsound Standard variance for arrays and function arguments Sound treatment of JavaScript this Careful separation of nominal and structural types Easy local rewriting of unsound idioms in 120,000 line corpus TypeScript has unsound typing rules to support common idioms 7

Safe TypeScript is Sound TypeScript is Intentionally Unsound Safe TypeScript guarantees type safety Combination of static checking and runtime checks Runtime-type-information (RTTI) based gradual typing Efficiency using two new notions of partial erasure Runtime overhead of only 15% for bootstrapping Safe TypeScript 6.5% for typed Octane benchmarks TypeScript uniformly erases all types making uses of any unsafe 8

9 Formalized core of Safe TypeScript, proven sound class C, interface I, {M;F}, number, any, Erased t Implemented in a branch of TypeScript v0.9.5 Can be invoked with --safe command line flag Evaluated on 120,000 lines of code Bootstrapped Safe TypeScript compiler, New TypeScript compiler, Octane Our Contributions

10 Safe TypeScript Tour Overview of RTTI-based Gradual Typing Values carry Run Time Type Tags consistent with their contents Dynamically-typed code instrumented to respect RTTI tags Invariant: v : [| v.tag |] Object with 3 fields and type tag f = 2 g = "s" h = true tag = {f:number; g:string}

interface Point { x:number } function g(p:Point) { p.x = p.x + 1; } function f() { var p:Point = { x = 0 }; g(p); } 11 Compiles unchanged No runtime checks No tagging ! Previous systems tag eagerly RTTI Tagging in Safe TypeScript On-demand and Differential Safe TypeScriptJavaScript

12 RTTI Tagging in Safe TypeScript On-demand function g(p:any) { p.x = p.x + 1; } function f() { var p:Point = { x = 0 }; g(p); } function f() { var p = { x = 0 }; g(shallowTag(p, Point)); } shallowTag(x,t) = x.tag := combine(x.tag, t); x Safe TypeScriptJavaScript Add RTTI when types lose precision

13 RTTI Tagging in Safe TypeScript Differential shallowTag(x,t) = x.tag := combine(x.tag, t); x interface 2dPoint extends Point { y:number } function h(p:any) {.. } function g(p:Point) { h(p); } function f() { var p:2dPoint = { x = 0; y = 0 }; g(p); } function g(p) { h(shallowTag(p, Point)); } function f() { var p = { x = 0; y = 0 }; g(shallowTag(p, { y:number })); } Safe TypeScriptJavaScript Add Minimum Required RTTI

14 RTTI Tagging in Safe TypeScript shallowTag(x,t) = x.tag := combine(x.tag, t); x function g(p) { h(shallowTag(p, Point)); } function f() { var p = { x = 0; y = 0 }; g(shallowTag(p, { y:number })); } JavaScript Add Minimum Required RTTI x = 0 y = 0

15 RTTI Tagging in Safe TypeScript shallowTag(x,t) = x.tag := combine(x.tag, t); x function g(p) { h(shallowTag(p, Point)); } function f() { var p = { x = 0; y = 0 }; g(shallowTag(p, { y:number })); } JavaScript Add Minimum Required RTTI x = 0 y = 0 tag = {y:number} x = 0 y = 0

16 RTTI Tagging in Safe TypeScript shallowTag(x,t) = x.tag := combine(x.tag, t); x function g(p) { h(shallowTag(p, Point)); } function f() { var p = { x = 0; y = 0 }; g(shallowTag(p, { y:number })); } JavaScript Add Minimum Required RTTI x = 0 y = 0 tag = {x:number; y:number} x = 0 y = 0 tag = {y:number} x = 0 y = 0

Differential Subtyping t1 d d = 0 | t d is loss in precision that must be captured in the RTTI 17 Differential Subtyping Technical Device for On-Demand and Differential Tagging

t 0 {x:number;y:number} {y:number} {x:number;y:number} Primitive RTTI Aware: number 0 18 Differential Subtyping t1 d d is loss in precision

Γ |- e : t2 ~> e’ t2 d Γ |- e : t1 ~> shallowTag(e’, d) 19 T-Sub Differential Subtyping t1 d d is loss in precision

20 Instrumentation of Dynamically Typed Code function g(p:any) { p.x = "boom" ; } function f() { var p:Point = { x = 0 }; g(p); assert(typeof p.x === "number"); } function f() {.. } function g(p) { write(p, "x", "boom" ); } write(o,f,v) = let t = o.tag; o[f] = check(v, t[f]); (Recall that f tags p with type Point ) // Fails Safe TypeScriptJavaScript

21 Differential Tagging Useful, But Not Ideal function g(p) { return p.x; } function f(p) { var p = { x = 0; y = 0 }; g(shallowTag(p, { y:number })); } Safe TypeScriptJavaScript function g(p:Point) { return p.x; } Unnecessary shallowTag function f() { var p:2dPoint = { x = 0; y = 0 }; g(p); }

22 Reason: Need Conservative Tagging Previous gradual type systems: t any for all static types t Incurs tagging even for statically typed code Relaxing it opens opportunities for sound type erasure

A new type modality: Erased t Erased t cannot be cast to any Statically a t but may not have an RTTI at runtime 23 Erased Types Programmer-controlled Tagging Behavior

t1 d t1 0 Erased t <\: any 24 Subtyping for Erased Types // Zero delta // Ensure full erasure is safe

25 Erased Types Example: No Tagging Safe TypeScriptJavaScript function g(p) { return p.x; } function f(p) { var p = { x = 0; y = 0 }; g(shallowTag(p, { y:number })); } function g(p:Point) { return p.x; } Unnecessary shallowTag function f() { var p:2dPoint = { x = 0; y = 0 }; g(p); }

26 Erased Types Example: No Tagging function g(p) { return p.x; } function f(p) { var p = { x = 0; y = 0 }; g(p); } Safe TypeScriptJavaScript function g(p:Erased Point) { return p.x; } function f() { var p:2dPoint = { x = 0; y = 0 }; g(p); } // No tagging Recall shallowTag for non-erased types

27 Erased Types Example: No Tagging function f(p) { var p = { x = 0; y = 0 }; g(p); } Safe TypeScriptJavaScript function g(p:Erased Point) { return h(p); } function f() { var p:2dPoint = { x = 0; y = 0 }; g(p); } // No tagging function h(p:any) {.. } Static Type Error

Obey a fully static type discipline (Sound type erasure, type abstraction, …) (Loss in expressiveness: not all code can be turned dynamic) Other advantages of Erased types Working with external libraries that may not have RTTI Adding new features to the type system (e.g. Polymorphism) See our paper for more details 28 Erased Types

29 Soundness Theorem: Forward Simulation Checks introduced by Safe TypeScript: Catch any dynamic type error Do not alter the semantics of type safe code Tag heap evolution invariant

Implemented in a branch of TypeScript v0.9.5 Invoke our type checker with --safe flag 10,000 Lines of Code Compiles to plain JavaScript (with instrumented checks) (recursive interfaces, inheritance, overloading, generics, arrays, external libs, …) 30 Safe TypeScript Implementation Open Source on Github

Bootstrapping Safe TypeScript 90,000 Lines of Code, heavily class based, carefully annotated Number of Errors Covariant method arguments 130 Variable scoping128 Potential unsound use of this 52 Bivariant array subtyping98...… Total478 Static Type Errors found in Safe TypeScript Code

Bootstrapping Safe TypeScript 90,000 Lines of Code, heavily class based, carefully annotated Static Type Errors found in Safe TypeScript Code All cases in one file using visitor pattern, easily rewritten Sloppy use of var declarations, easily fixed Projection of methods, easily fixed by making them functions Fixed by introducing array mutability qualifiers Number of Errors Covariant method arguments 130 Variable scoping128 Potential unsound use of this 52 Bivariant array subtyping98...… Total478

Bootstrapping Safe TypeScript 90,000 Lines of Code, heavily class based, carefully annotated 478 Static type errors 26 failed runtime downcasts; 5 in our own code ! 15% runtime overhead of type safety

Octane Benchmarks (6 / 17) 22x (ave.) and 72x (max.) overhead with no type annotations Down to 6.5% after adding type annotations No overhead for statically-typed code Found a variable scoping bug in navier-stokes It has since been fixed Efficiency conditioned on precise type inference TypeScript quite conservative

Nominal handling of prototype-based classes Sound handling of this Abstraction theorem for Erased { } Zero-subtyping to avoid object identity issues More experiments (TypeScript v1.1, Octane benchmarks, Different tagging schemes) 35 Also in the paper …

When to use Safe TypeScript ? For mature TypeScript projects, improved code quality Good in development setting for finding early bugs Baseline for JS analyses focusing on deeper properties 36 Safe TypeScript Summary Safe & Efficient Gradual Typing for TypeScript Significant value for type annotations at a modest cost (runtime checks at least during development and testing) Significant value for type annotations at a modest cost (runtime checks at least during development and testing) Give it a go !

37 interface Point {..} interface 2dPoint {..} Erased Types Example: Type Abstraction function g(p:Point) { write(p, "y", 3); } function f() {..} RTTI of p at write is {y:number} write succeeds: abstraction violation function g(p:Point) { ( p).y = 3; } function f() { var p:2dPoint = {x = 0;y = 0}; g(p); } Safe TypeScriptJavaScript

38 function g(p:Point) { ( p).y = 3; } function f() { var p:2dPoint = {x = 0;y = 0}; g(p); } interface Point extends Erased {..} interface 2dPoint extends Point {..} Static Type Error Erased Types Example: Type Abstraction Safe TypeScriptJavaScript