/
Safe & Efficient Gradual Safe & Efficient Gradual

Safe & Efficient Gradual - PowerPoint Presentation

liane-varnes
liane-varnes . @liane-varnes
Follow
448 views
Uploaded On 2016-04-07

Safe & Efficient Gradual - PPT Presentation

Typing for TypeScript Aseem Rastogi University of Maryland College Park Nikhil Swamy Cédric Fournet Gavin Bierman Panagiotis Vekris Microsoft Research ID: 276126

function typescript type safe typescript function safe type number point shallowtag var javascript erased tagging tag rtti types code static 2dpoint runtime

Share:

Link:

Embed:

Download Presentation from below link

Download Presentation The PPT/PDF document "Safe & Efficient Gradual" is the property of its rightful owner. Permission is granted to download and print the materials on this web site for personal, non-commercial use only, and to display it on your personal computer provided you do not modify the materials and that you retain all copyright notices contained in the materials. By downloading content from our website, you accept the terms of this agreement.


Presentation Transcript

Slide1

Safe & Efficient Gradual Typingfor TypeScript

Aseem RastogiUniversity of Maryland, College ParkNikhil Swamy Cédric Fournet Gavin Bierman Panagiotis Vekris (Microsoft Research) (Oracle) (UCSD)Slide2

Gradual TypingCombines benefits of static and dynamic typing

2Statically-typed fragmentDynamically-typed fragment

Dynamic type

any

Runtime

checks mediate

interaction

Static

type errors

Performance

Typed interface documentation

Rapid prototyping

FlexibilitySlide3

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

I

ncreasing Adoption in Industry

M

ainly for

JavaScriptSlide4

TypeScript is Intentionally UnsoundFor 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)4Slide5

Programmers Cannot Rely On Types5

private parseColorCode (c:string) { if (typeof c !==

"

string"

)

return

-1;

}

Snippet from

TouchDevelop, a large TypeScript DevelopmentTools can’t rely on typesRefactoring, compiler optimizations, etc. are not safeSlide6

6Can we design a gradual type system that is:

SafeEfficientSupports idiomatic TypeScript/JavaScriptWe present Safe TypeScriptSlide7

Safe TypeScript is Sound

TypeScript is Intentionally UnsoundStandard variance for arrays and function argumentsSound treatment of JavaScript thisCareful 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

7Slide8

Safe TypeScript is Sound

TypeScript is Intentionally UnsoundSafe TypeScript guarantees type safetyCombination of static checking and runtime checksRuntime-type-information (RTTI) based gradual typingEfficiency using two new notions of partial erasureRuntime overhead of only 15% for bootstrapping Safe TypeScript

6.5% for typed Octane benchmarks

TypeScript uniformly erases all types

making uses of

any

unsafe

8Slide9

9Formalized

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

O

ur ContributionsSlide10

10Safe TypeScript Tour

Overview of RTTI-based Gradual TypingValues carry Run Time Type Tagsconsistent with their contentsDynamically-typed code i

nstrumented

to

respect

RTTI

tags

Invariant: v : [|

v.tag

|]

Object with 3 fields and type tag

f = 2g = "s"h = truetag = {f:number; g:string}Slide11

interface Point { x:

number }function g(p:Point) { p.x = p.x + 1;}

function

f() {

var

p:Point = { x = 0 };

g(

p);

}11

Compiles unchangedNo runtime checksNo tagging !

Previous systems tag eagerly

RTTI Tagging in Safe TypeScript

On-demand and Differential

Safe TypeScript

JavaScriptSlide12

12

RTTI Tagging in Safe TypeScriptOn-demandfunction 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 TypeScript

JavaScript

Add RTTI when types lose precisionSlide13

13

RTTI Tagging in Safe TypeScriptDifferentialshallowTag(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 TypeScript

JavaScript

Add Minimum Required RTTISlide14

14

RTTI Tagging in Safe TypeScriptshallowTag(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 }));}JavaScriptAdd Minimum Required RTTI

x = 0

y = 0Slide15

15

RTTI Tagging in Safe TypeScriptshallowTag(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 }));}JavaScriptAdd Minimum Required RTTI

x = 0

y = 0

tag = {y:number}

x = 0

y = 0Slide16

16

RTTI Tagging in Safe TypeScriptshallowTag(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 }));}JavaScriptAdd Minimum Required RTTI

x = 0

y = 0

tag = {x:number; y:number}

x = 0

y = 0

tag = {y:number}

x = 0

y = 0Slide17

Differential Subtypingt1

<: t2 ~> d d = 0 | td is loss in precision that must be captured in the RTTI17

D

ifferential Subtyping

Technical Device

for On-Demand and Differential TaggingSlide18

t <: t ~> 0{

x:number;y:number} <: {x:number} ~> {y:number}{x:number

;y:

number

} <:

any

~> {

x:

number

;y:number

}Primitive RTTI Aware: number <: any

~> 018Differential Subtypingt1 <: t2 ~> d d is loss in precisionSlide19

Γ |- e : t2 ~> e’t2 <: t1 ~> d

Γ |- e : t1 ~> shallowTag(e’, d) 19T-Sub

Differential Subtyping

t1

<: t2 ~> d d

is

loss

in

precisionSlide20

20

Instrumentation of Dynamically Typed Codefunction 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 TypeScript

JavaScriptSlide21

21Differential 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 TypeScriptJavaScriptfunction g(p:Point) { return p.x;

}

Unnecessary

shallowTag

function

f() {

var

p:2dPoint = { x = 0; y = 0 };

g(p);

}Slide22

22Reason: 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 erasureSlide23

A new type modality: Erased

tErased t cannot be cast to anyStatically a tbut may not have an RTTI at runtime

23

Erased Types

Programmer-controlled Tagging BehaviorSlide24

t1 <: t2 ~> dt1

<: Erased t2 ~> 0Erased t <\: any24

Subtyping for Erased Types

// Zero delta

// Ensure full erasure is safe Slide25

25Erased 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);

}Slide26

26Erased Types Example: No Tagging

function g(p) { return p.x; }

function

f(p) {

var

p = { x = 0; y = 0 };

g

(p)

;

}Safe TypeScript

JavaScriptfunction 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 typesSlide27

27Erased Types Example: No Tagging

function f(p) { var p = { x = 0; y = 0 }; g(p)

;

}

Safe TypeScript

JavaScript

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 Slide28

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 typesWorking with external libraries that may not have RTTIAdding new features to the type system (e.g. Polymorphism)

See our paper for more details

28

Erased

TypesSlide29

29Soundness Theorem: Forward Simulation

Checks introduced by Safe TypeScript:Catch any dynamic type errorDo not alter the semantics of type safe code

Tag heap evolution invariantSlide30

Implemented in a branch of TypeScript v0.9.5

Invoke our type checker with --safe flag10,000 Lines of CodeCompiles to plain JavaScript (with instrumented checks)(recursive interfaces, inheritance, overloading, generics, arrays, external libs, …)30

Safe TypeScript Implementation

Open Source on GithubSlide31

Bootstrapping Safe TypeScript

90,000 Lines of Code, heavily class based, carefully annotatedNumber of Errors

Covariant method

arguments

130

Variable scoping

128

Potential unsound use of

this

52

Bivariant array subtyping98...…Total478 Static Type Errors found in Safe TypeScript CodeSlide32

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 scoping

128

Potential unsound use of

this

52

Bivariant

array subtyping

98

...

Total

478Slide33

Bootstrapping Safe TypeScript

90,000 Lines of Code, heavily class based, carefully annotated478 Static type errors26 failed runtime downcasts; 5 in our own code !15% runtime overhead of type safetySlide34

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

inferenceTypeScript quite conservativeSlide35

Nominal handling of prototype-based classesSound handling of thisAbstraction theorem for

Erased { }Zero-subtyping to avoid object identity issuesMore experiments(TypeScript v1.1, Octane benchmarks, Different tagging schemes)35Also in the paper …Slide36

When to use Safe TypeScript ?

For mature TypeScript projects, improved code qualityGood in development setting for finding early bugsBaseline for JS analyses focusing on deeper properties36Safe 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)

Give it a go !Slide37

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) {

(<

any

> p).y = 3;

}

function

f() {

var

p:2dPoint =

{x = 0;y

=

0}

;

g(p);

}

Safe TypeScript

JavaScriptSlide38

38

function g(p:Point) { (<any> 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 TypeScript

JavaScript