Intensional Polymorphism in Type-Erasure Semantics Karl Crary, Stephanie Weirich, Greg Morrisett

advertisement
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
TypeTypeType
the kind of the pair-type function
pairT [int] [string]
this gives us the type (int  string)
Now add the typecase construct:
typecase [.int] 
int  0
substitute  for  and return an int
iML syntax
 ::= Type | 
c ::=  | int | cc | 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
kinds:
Type
types:
int
values:
5
TypeType
intint
6
.
x:int.x
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 valuepassing
• As a bonus, gain some abstraction
Overview of type representations
R(Rint,Rint)
The representation of intint
R( R(int)R(int) )
Its type
Syntax of R
 ::= Type | 
c ::=  | int | cc | 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 : dynamicstring
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
Download