Transcript
Page 1: Space-Efficient Gradual Typing

1

Space-Efficient Gradual Typing

David HermanNortheastern University

Aaron Tomb, Cormac FlanaganUniversity of California, Santa Cruz

Page 2: Space-Efficient Gradual Typing

2

The point

Naïve type conversions in functional programming languages are not safe for space.

But they can and should be.

Page 3: Space-Efficient Gradual Typing

3

Gradual Typing:

Software evolution via hybrid type checking

Page 4: Space-Efficient Gradual Typing

4

Dynamic vs. static typing

DynamicTyping

StaticTyping

Page 5: Space-Efficient Gradual Typing

5

Gradual typing

DynamicTyping

StaticTyping

Page 6: Space-Efficient Gradual Typing

6

Type checking

let x = f() in … let y : Int = x - 3 in …

Page 7: Space-Efficient Gradual Typing

7

Type checking

let x : ? = f() in … let y : Int = x - 3 in …

Page 8: Space-Efficient Gradual Typing

8

Type checking

let x : ? = f() in … let y : Int = x - 3 in …

- : Int × Int → Int

Page 9: Space-Efficient Gradual Typing

9

Type checking

let x : ? = f() in … let y : Int = <Int>x - 3 in …

Page 10: Space-Efficient Gradual Typing

10

Type checking

let x : ? = f() in … let y : Int = <Int>x - 3 in …

Int

Page 11: Space-Efficient Gradual Typing

11

Evaluation

let x : ? = f() in … let y : Int = <Int>x - 3 in …

Page 12: Space-Efficient Gradual Typing

12

Evaluation

let x : ? = 45 in … let y : Int = <Int>x - 3 in …

Page 13: Space-Efficient Gradual Typing

13

Evaluation

let y : Int = <Int>45 - 3 in …

Page 14: Space-Efficient Gradual Typing

14

Evaluation

let y : Int = 45 - 3 in …

Page 15: Space-Efficient Gradual Typing

15

Evaluation

let y : Int = 42 in …

Page 16: Space-Efficient Gradual Typing

16

Evaluation (take 2)

let x : ? = f() in … let y : Int = <Int>x - 3 in …

Page 17: Space-Efficient Gradual Typing

17

Evaluation (take 2)

let x : ? = true in … let y : Int = <Int>x - 3 in …

Page 18: Space-Efficient Gradual Typing

18

Evaluation (take 2)

let y : Int = <Int>true - 3 in …

Page 19: Space-Efficient Gradual Typing

19

Evaluation (take 2)

error: “true is not an Int”

Page 20: Space-Efficient Gradual Typing

20

Space Leaks

Page 21: Space-Efficient Gradual Typing

21

Space leaks

fun even(n) = if (n = 0) then true else odd(n - 1)

fun odd(n) = if (n = 0) then false else even(n - 1)

Page 22: Space-Efficient Gradual Typing

22

Space leaks

fun even(n : Int) = if (n = 0) then true else odd(n - 1)

fun odd(n : Int) : Bool = if (n = 0) then false else even(n - 1)

Page 23: Space-Efficient Gradual Typing

23

Space leaks

fun even(n : Int) = if (n = 0) then true else odd(n - 1)

fun odd(n : Int) : Bool = if (n = 0) then false else <Bool>even(n - 1)

Page 24: Space-Efficient Gradual Typing

24

Space leaks

fun even(n : Int) = if (n = 0) then true else odd(n - 1)

fun odd(n : Int) : Bool = if (n = 0) then false else <Bool>even(n - 1)

non-tail call!

Page 25: Space-Efficient Gradual Typing

25

Space leaks

even(n)→* odd(n - 1)→* <Bool>even(n - 2)→* <Bool>odd(n - 3)→* <Bool><Bool>even(n - 4)→* <Bool><Bool>odd(n - 5)→* <Bool><Bool><Bool>even(n - 6)→* …

Page 26: Space-Efficient Gradual Typing

26

Naïve Function Casts

Page 27: Space-Efficient Gradual Typing

27

Casts in functional languages<Int>n → n<Int>v → error: “failed cast” (if v∉Int)

<σ→τ>λx:?.e → …

Page 28: Space-Efficient Gradual Typing

28

Casts in functional languages<Int>n → n<Int>v → error: “failed cast” (if v∉Int)

<σ→τ>λx:?.e → λz:σ.<τ>((λx:?.e) z)

Very useful, very popular… unsafe for space.fresh, typed proxy

cast result

Page 29: Space-Efficient Gradual Typing

29

More space leaks

fun evenk(n : Int, k : ? → ?) = if (n = 0) then k(true) else oddk(n – 1, k)

fun oddk(n : Int, k : Bool → Bool) = if (n = 0) then k(false) else evenk(n – 1, k)

Page 30: Space-Efficient Gradual Typing

30

More space leaks

fun evenk(n : Int, k : ? → ?) = if (n = 0) then k(true) else oddk(n – 1, <Bool→Bool>k)

fun oddk(n : Int, k : Bool → Bool) = if (n = 0) then k(false) else evenk(n – 1, <?→?>k)

Page 31: Space-Efficient Gradual Typing

31

More space leaks

evenk(n, k0)

→* oddk(n - 1, <Bool→Bool>k0)

→* oddk(n - 1, λz:Bool.<Bool>k0(z))→* evenk(n - 2, <?→?>λz:Bool.<Bool>k0(z))

→* evenk(n - 2, λy:?.(λz:Bool.<Bool>k0(z))(y))→* oddk(n - 3, <Bool→Bool>λy:?.(λz:Bool.<Bool>k0(z))(y))

→* oddk(n – 3, λx:Bool.(λy:?.(λz:Bool.<Bool>k0(z))(y))(x))

→* evenk(n - 4, <?→?>λx:Bool.(λy:?.(λz:Bool.<Bool>k0(z))(y))(x))

→* evenk(n - 4, λw:?.(λx:Bool.(λy:?.(λz:Bool.<Bool>k0(z))(y))(x))(w))→* oddk(n - 5, <Bool→Bool>λw:?.(λx:Bool.(λy:?.(λz:Bool.<Bool>k0(z))(y))(x))(w))

→* oddk(n - 5, λv:Bool.<Bool>(λw:?.(λx:Bool.(λy:?.(λz:Bool.<Bool>k0(z))(y))(x))(w))(v))

→* …

(…without even using k0!)

Page 32: Space-Efficient Gradual Typing

32

Space-Efficient Gradual Typing

Page 33: Space-Efficient Gradual Typing

33

Intuition

Casts are like function restrictions(Findler and Blume, 2006)

Can their representation exploit the properties of restrictions?

Page 34: Space-Efficient Gradual Typing

34

Exploiting algebraic properties

Closure under composition:

<Bool>(<Bool> v) = (<Bool>◦<Bool>) v

Page 35: Space-Efficient Gradual Typing

35

Exploiting algebraic properties

Idempotence:

<Bool>(<Bool> v) = (<Bool>◦<Bool>) v

= <Bool> v

Page 36: Space-Efficient Gradual Typing

36

Exploiting algebraic properties

Distributivity:

(<?→?>◦<Bool→Bool>) v = <(Bool◦?)→(?◦Bool)> v

Page 37: Space-Efficient Gradual Typing

37

Space-efficient gradual typing Generalize casts to coercions

(Henglein, 1994) Change representation of casts

from <τ> to <c> Merge casts at runtime:

<c>(<d> e) → <c◦d>e

merged before evaluating e

This coercion can be

simplified!

Page 38: Space-Efficient Gradual Typing

38

Space-efficient gradual typing Generalize casts to coercions

(Henglein, 1994) Change representation of casts

from <τ> to <c> Merge casts at runtime:

<c>(<d> e) → <c◦d>e

→ <c′>e

Page 39: Space-Efficient Gradual Typing

39

Tail recursion

even(n)→* odd(n - 1)→* <Bool>even(n - 2)→* <Bool>odd(n - 3)→* <Bool><Bool>even(n - 4)→* <Bool>even(n - 4)→* <Bool>odd(n - 5)→* <Bool><Bool>even(n - 6)→* <Bool>even(n - 6)→* …

Page 40: Space-Efficient Gradual Typing

40

Bounded proxies

evenk(n, k0)

→* oddk(n - 1, <Bool→Bool>k0)

→* evenk(n - 2, <?→?><Bool→Bool>k0)

→* evenk(n - 2, <Bool→Bool>k0)

→* oddk(n - 3, <Bool→Bool>k0)

→* evenk(n - 4, <?→?><Bool→Bool>k0)

→* evenk(n - 4, <Bool→Bool>k0)

→* oddk(n - 5, <Bool→Bool>k0)→* …

Page 41: Space-Efficient Gradual Typing

41

Guaranteed.

Theorem: any program state S during evaluation of a program P is bounded by

kP · sizeOR(S)

sizeOR(S) = size of S without any casts

Page 42: Space-Efficient Gradual Typing

42

Related work

Gradual typing Siek and Taha (2006, 2007)

Function proxies Findler and Felleisen (1998, 2006): Software contracts Gronski, Knowles, Tomb, Freund, Flanagan (2006):

Hybrid typing, Sage Tobin-Hochstadt and Felleisen (2006):

Interlanguage migration Coercions

Henglein (1994): Dynamic typing Space efficiency

Clinger (1998): Proper tail recursion

Page 43: Space-Efficient Gradual Typing

43

Contributions

Space-safe representation and semantics of casts for functional languages

Supports function casts and tail recursion Three implementation strategies

(coercion-passing style, trampoline, continuation marks)

Earlier error detection (see paper) Proof of space efficiency

Page 44: Space-Efficient Gradual Typing

44

The point, again

Naïve type conversions in functional programming languages are not safe for space.

But they can and should be.

Thank [email protected]


Recommended