66
1 Space-Efficient Gradual Typing David Herman Northeastern University Aaron Tomb, Cormac Flanagan University of California, Santa Cruz

Space-Efficient Gradual Typing

  • Upload
    taro

  • View
    25

  • Download
    0

Embed Size (px)

DESCRIPTION

Space-Efficient Gradual Typing. David Herman Northeastern University Aaron Tomb, Cormac Flanagan University of California, Santa Cruz. The point. Naïve type conversions in functional programming languages are not safe for space. But they can and should be. Gradual Typing: - PowerPoint PPT Presentation

Citation preview

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

Static semantics (Siek & Taha)

Type compatibility

E ⊢ e1 : (S→T) E ⊢ e2 : S′ S′ ~: S

E ⊢ (e1 e2) : T

Page 21: Space-Efficient Gradual Typing

21

Static semantics (Siek & Taha)

Type compatibility

E ⊢ e1 : (S→T) E ⊢ e2 : S′ S′ ~: S

E ⊢ (e1 e2) : T

Page 22: Space-Efficient Gradual Typing

22

Static semantics (Siek & Taha)

Type compatibility ≠ subtyping!

T ~: T T ~: ? ? ~: T

T1 ~: S1 S2 ~: T2

(S1→S2) ~: (T1→T2)

Page 23: Space-Efficient Gradual Typing

23

Static semantics (Siek & Taha)

Cast insertion

E ⊢ e1 ↪ t1 : (S→T) E ⊢ e2 ↪ t2 : S′ S′ ~: S

E ⊢ (e1 e2) ↪ (t1 (<S> t2)) : T

E ⊢ e ↪ t : T

cast argument expression

Page 24: Space-Efficient Gradual Typing

24

Space Leaks

Page 25: Space-Efficient Gradual Typing

25

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 26: Space-Efficient Gradual Typing

26

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 27: Space-Efficient Gradual Typing

27

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 28: Space-Efficient Gradual Typing

28

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 29: Space-Efficient Gradual Typing

29

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 30: Space-Efficient Gradual Typing

30

Naïve Function Casts

Page 31: Space-Efficient Gradual Typing

31

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

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

Page 32: Space-Efficient Gradual Typing

32

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

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

Very useful, very popular… unsafe for space.

fresh, typed proxy

cast result

Page 33: Space-Efficient Gradual Typing

33

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 34: Space-Efficient Gradual Typing

34

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 35: Space-Efficient Gradual Typing

35

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 36: Space-Efficient Gradual Typing

36

Space-Efficient Gradual Typing

Page 37: Space-Efficient Gradual Typing

37

Intuition

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

Can their representation exploit the properties of restrictions?

Page 38: Space-Efficient Gradual Typing

38

Exploiting algebraic properties

Closure under composition:

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

Page 39: Space-Efficient Gradual Typing

39

Exploiting algebraic properties

Idempotence:

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

= <Bool> v

Page 40: Space-Efficient Gradual Typing

40

Exploiting algebraic properties

Distributivity:

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

Page 41: Space-Efficient Gradual Typing

41

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 42: Space-Efficient Gradual Typing

42

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 43: Space-Efficient Gradual Typing

43

Static semantics

Type compatibility

E ⊢ e1 : (S→T) E ⊢ e2 : S′ S′ ~: S

E ⊢ (e1 e2) : T

Page 44: Space-Efficient Gradual Typing

44

Static semantics

Type compatibility

T ~: T T ~: ? ? ~: T

T1 ~: S1 S2 ~: T2

(S1→S2) ~: (T1→T2)

Page 45: Space-Efficient Gradual Typing

45

Static semantics

Cast insertion

E ⊢ e1 ↪ t1 : (S→T) E ⊢ e2 ↪ t2 : S′ c=coerce(S′, S)

E ⊢ (e1 e2) ↪ (t1 (<c> t2)) : T

E ⊢ e ↪ t : T

computes a type

coercionreplaces the

type cast with a coercion

Page 46: Space-Efficient Gradual Typing

46

Henglein’s coercions

c ::= Succ | Fail | D! | D? | Fun c c | c◦cD ::= Int | Bool | Fun

coerce(T, T) = Succcoerce(Int, ?) = Int!coerce(?, Int) = Int?

Page 47: Space-Efficient Gradual Typing

47

Henglein’s coercions

c ::= Succ | Fail | D! | D? | Fun c c | c◦cD ::= Int | Bool | Fun

coerce(S1→S2, T1→T2) =Fun coerce(T1, S1) coerce(S2, T2)

coerce(?, T1→T2) =coerce(?→?, T1→T2)◦Fun?

coerce(T1→T2, ?) =Fun!◦coerce(T1→T2, ?→?)

Page 48: Space-Efficient Gradual Typing

48

Coercion normalization

c◦Succ = cSucc◦c = c

c◦Fail = FailFail◦c = Fail

D?◦D! = SuccInt?◦Bool! = Fail

(Fun d1 d2)◦(Fun c1 c2) = Fun (c1◦d1) (d2◦c2)

Page 49: Space-Efficient Gradual Typing

49

Dynamic semantics

v ::= u | <c> uu ::= n | b | λx:S.t

Page 50: Space-Efficient Gradual Typing

50

Dynamic semantics

E ::= [] | (E t) | (v E) | <c> PP ::= [] | (E t) | (v E)

E[<c> (<d> t)] → E[<c◦d> t]E[(λx:S.t) v] → E[t[v/x]]E[(<Fun c d> u) v] → E[<d> (u (<c> v))]E[<Succ> u] → E[u]

(if E ≠ E′[<c> []])E[<Fail> u] → error

(if E ≠ E′[<c> []])

Page 51: Space-Efficient Gradual Typing

51

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 52: Space-Efficient Gradual Typing

52

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 53: Space-Efficient Gradual Typing

53

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 54: Space-Efficient Gradual Typing

54

Earlier error detection

<Int→Int>(<Bool→Bool> e)

→ <Fail→Fail> e

→ error: “Int→Int ≠ Bool→Bool”

Page 55: Space-Efficient Gradual Typing

55

Earlier error detection

E ::= [] | (E t) | (v E) | <c> PP ::= [] | (E t) | (v E)

E[<c> (<d> t)] → E[<c◦d> t]E[(λx:S.t) v] → E[t[v/x]]E[(<Fun c d> u) v] → E[<d> (u (<c> v))]E[<Succ> u] → E[u]

(if E ≠ E′[<c> []])E[<Fail> t] → error

(if E ≠ E′[<c> []])

why bother evaluating t?

Page 56: Space-Efficient Gradual Typing

56

Implementation

Page 57: Space-Efficient Gradual Typing

57

Coercions as continuation marks

E [<?→?><Bool→Bool> e]

E

Page 58: Space-Efficient Gradual Typing

58

Coercions as continuation marks

E [<?→?><Bool→Bool> e]

E

?→?

Page 59: Space-Efficient Gradual Typing

59

Coercions as continuation marks

E [<Bool→Bool> e]

E

?→?

Page 60: Space-Efficient Gradual Typing

60

Coercions as continuation marks

E [<Bool→Bool> e]

E

Bool→Bool

Page 61: Space-Efficient Gradual Typing

61

Coercions as continuation marks

E [e]

E

Bool→Bool

Page 62: Space-Efficient Gradual Typing

62

Alternative approaches

Coercion-passing style

λ(x,c).f(x,simplify(c◦d))

Trampoline

λ(x).(d,λ().f(x))

Page 63: Space-Efficient Gradual Typing

63

Parting Thoughts

Page 64: Space-Efficient Gradual Typing

64

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 Clements (2004): Security-passing style

Page 65: Space-Efficient Gradual Typing

65

Contributions

Space-safe representation and semantics of casts for functional languages

Supports function casts and tail recursion Earlier error detection Proof of space efficiency Three implementation strategies

Page 66: Space-Efficient Gradual Typing

66

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]