24
Intensional Polymorphism in Type- Erasure Semantics Karl Crary, Stephanie Weirich, Greg Morrisett Presentation by Nate Waisbrot

Intensional Polymorphism in Type-Erasure Semantics Karl Crary, Stephanie Weirich, Greg Morrisett Presentation by Nate Waisbrot

  • View
    223

  • Download
    1

Embed Size (px)

Citation preview

Intensional Polymorphism in Type-Erasure Semantics

Karl Crary, Stephanie Weirich, Greg Morrisett

Presentation by Nate Waisbrot

Authors' background

Part of Cornell University's TAL (Typed Assembly Language) group

Creating intermediate languages to compile into TAL

Three styles of polymorphism

• Get a value and inspect its type– Easy and efficient, but not powerful

• Pass types as first-class objects– Powerful, but slow and complicated for the

compiler

• Pass values which represent types– Best of both worlds

Passing values

• Recall the paper "Dynamically Typing in a Statically Typed Language" (Abadi, Cardelli, Pierce, and Plotkin)

• Types are tied to values -- you can't have one without the other

Dynamic types

Dynamic(5 int) dynamic value

f : dynamic dynamic dynamic function

x:dynamic. typecase x of

int …

Passing types

• Values are described by types

• Types are described by kinds

• We could keep going… (System F)

Overview of System F

.x:.x The polymorphic identity function

. The type of the identity function

iden [int] 5 Application of the identity function

..x:.y:. (x y) a pair function

.. ( ) its type

pair [int] [string] 0 “zero” application

Overview of iML

Start with System F, add the ability to work with types alone

.. the pair-type function

TypeTypeType the kind of the pair-type function

pairT [int] [string] this gives us the type (int string)

Now add the typecase construct:

typecase [.int] substitute for and return an int

int 0

iML syntax

::= Type |

c ::= | int | cc | c c | :.c | c c | Typerec c(cint, c, c)

::= c | | | :.

e ::= x | i | x:.e | fix f:.v | e e | <e,e> | e | :.v | e[c] |

typecase [.] …

v::= i | x:.e | fix f:.v | <v,v> | :.v

Typing hierarchy

5 6 x:int.x

int intint

Type

types:

values:

.

TypeTypekinds:

What's wrong with type passing?

• Types must be kept separate from values– Doubles the type-checker's work– Compiling it down to TAL is hard

• Language semantics require types to always be passed

Solution: type representations

• Make new type, "representation"

• Get back all the simplicity of normal value-passing

• As a bonus, gain some abstraction

Overview of type representations

R(Rint,Rint) The representation of intint

R( R(int)R(int) ) Its type

Syntax of R

::= Type |

c ::= | int | cc | c c | :.c | c c | R(c) |

Typerec c(cint, c, c, cR)

::= c | | | :. | :.

e ::= x | i | x:.e | fix f:.v | e e | <e,e> | e | :.v | e[c] |

pack e as . hiding | unpack <,x> = e in e

| Rint | R(e,e) | R(e,e) | RR(e) | typecase [.c] …

v::= i | x:.e | fix f:.v | <v,v> | :.v |

pack v as . hiding | Rint | R(v,v) | R(v,v) | RR(v)

TypeToString: dynamic types

typeToString : dynamicstring

x:dynamic.

typecase x of

int "int"

string "string"

"function"

× "<" + typeToString Dynamic( 1x)

+ "," + typeToString Dynamic( 2x) + ">"

TypeToString: type-passing

fix typeToString : :Type.string .

:Type.

typecase [.string] of

int "int"

string "string"

typeToString [] + "" + typeToString []

× "<" + typeToString []

+ "," + typeToString [] + ">"

TypeToString: type representations

fix typeToString : :Type.R()string .

:Type.x:R().

typecase [.string] x of

Rint "int"

Rstring "string"

R(x,y) as typeToString [] x

+ "" + typeToString [] y

R×(x,y) as × "<" + typeToString [] x

+ "," + typeToString [] y + ">"

Type erasure

• A well-typed program in typed -calculus has an equivalent in untyped -calculus

Typed: x:.x

Untyped: x.x

TypeToString: with types erased

fix typeToString : :Type.R()string .

:Type.x:R().

typecase [.string] x of

Rint "int"

Rstring "string"

R(x,y) as typeToString [] x

+ "" + typeToString [] y

R×(x,y) as × "<" + typeToString [] x

+ "," + typeToString [] y + ">"

Type refinement

• Do dead-code elimination based on the type of the representation

• Propagate information about the type of an argument back through the function

Monomorphic closure

x:.y A function with a free variable

Its type (if y has type )

We want to eliminate free variables

f = ((x e): env.ye) <y> The closed function

env.(( env) ) env Its type

Polymorphic closure

The same closed function, with type passing

:Kind. env:Type. :. :=.

(( env) ) env

Closure with representations

f’ = x:( R()). 2 x

f’ : ( R())

f’’ = pack (f’’ R) as env.(( env) ) env

hiding R()

f’’ : env.(( env) ) env

Summary

• Create a value to represent a type

• Pass the value, not the type

• Passing values is easy

• Knowing types at runtime is useful