transposing f to c transposing f to c andrew kennedy & don syme microsoft research cambridge,...

24
Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Andrew Kennedy & Don Syme Microsoft Research Microsoft Research Cambridge, U.K. Cambridge, U.K.

Upload: ashley-padilla

Post on 26-Mar-2015

218 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

Transposing F to CTransposing F to C♯♯

Andrew Kennedy & Don SymeAndrew Kennedy & Don SymeMicrosoft Research Microsoft Research

Cambridge, U.K.Cambridge, U.K.

Page 2: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

Transposing what?Transposing what?

As musical keys, F and CAs musical keys, F and C♯ ♯ are far apartare far apart As programming languages, (System) F and As programming languages, (System) F and

(Generic) C(Generic) C♯♯ are far apart are far apart But (message of talk):But (message of talk):

Polymorphism in Generic C♯ is as expressive as

polymorphism in System F

Page 3: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

Polymorphic Programming Polymorphic Programming LanguagesLanguages

Standard ML

O’Caml

Eiffel

Ada

C♯ (coming soon…)♯ (coming soon…)

GJ

C++

MercuryClu

Page 4: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

Polymorphic featuresPolymorphic features

Parameterized datatypes

Parameterized classes

Polymorphic functions

For-all types

Polymorphic methods

Bounds on type parametersConstraints on type parameters

Higher-order polymorphism & kinds

Impredicative polymorphism

Type classes

Variance

Page 5: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

System F and CSystem F and C♯ ♯

System F (a.k.a. polymorphic lambda System F (a.k.a. polymorphic lambda calculus) is very different from Ccalculus) is very different from C♯♯

System FSystem F Generic CGeneric C♯ ♯

Structural equivalence for Structural equivalence for typestypes

Name equivalence for typesName equivalence for types

No subtypingNo subtyping Subtyping & inheritanceSubtyping & inheritance

First-class functionsFirst-class functions Virtual methodsVirtual methods

Quantified typesQuantified types(“first-class polymorphism”)(“first-class polymorphism”)

Parameterized classes & Parameterized classes & polymorphic methodspolymorphic methods

Page 6: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

System F into CSystem F into C♯ ♯

Despite these differences, we can Despite these differences, we can formalize a translation from System F into formalize a translation from System F into (Generic) C(Generic) C♯♯ that that is fully type-preserving (no loss of information)is fully type-preserving (no loss of information) is sound (preserves program behaviour)is sound (preserves program behaviour) (second message of talk) demonstrates that…(second message of talk) demonstrates that…

polymorphic virtual methodsexpress

first-class polymorphism

Page 7: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

ML-style polymorphism into ML-style polymorphism into CC♯ ♯

Define a datatype: Define a datatype:

datatype ’a Tree = Leaf of ’a | Node of ’a Tree*’a Treedatatype ’a Tree = Leaf of ’a | Node of ’a Tree*’a Tree

Write a polymorphic function:Write a polymorphic function:

fun reflect (t : ’a Tree) =fun reflect (t : ’a Tree) =case t ofcase t of Leaf a => Leaf a Leaf a => Leaf a| Node(l,r) => Node(reflect r,reflect l)| Node(l,r) => Node(reflect r,reflect l)

Page 8: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

Compare:Compare:

Define parameterized classes: Define parameterized classes: abstract class Tree<A> { ... }abstract class Tree<A> { ... }class Leaf<A> : Tree<A> { A value; ... }class Leaf<A> : Tree<A> { A value; ... }class Node<A> : Tree<A> { Tree<A> left; Tree<A> right; ... }class Node<A> : Tree<A> { Tree<A> left; Tree<A> right; ... }

Add a method:Add a method:abstract class Tree<A> { virtual Tree<A> reflect(); } abstract class Tree<A> { virtual Tree<A> reflect(); } class Leaf<A> : Tree<A> { ...class Leaf<A> : Tree<A> { ... override Tree<A> reflect() { override Tree<A> reflect() { return this; } return this; } } } class Node<A> : Tree<A> { ...class Node<A> : Tree<A> { ... override Tree<A> reflect() { override Tree<A> reflect() { return new Node<A>(right.reflect(), left.reflect()); } return new Node<A>(right.reflect(), left.reflect()); }}}

Page 9: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

In generalIn general

ML-style datatypes can be translated into ML-style datatypes can be translated into parameterized classesparameterized classes

Polymorphic functions can be translated Polymorphic functions can be translated into methods inside a parameterized class into methods inside a parameterized class e.g.e.g.

class Mapper<A,B> {class Mapper<A,B> { List<B> Map(Function<A,B> f, List<A> xs) { ... List<B> Map(Function<A,B> f, List<A> xs) { ...} }

List<int> li = ...;List<int> li = ...;List<string> ls = new Mapper<int,string>().Map(myFun, List<string> ls = new Mapper<int,string>().Map(myFun, li);li);

Page 10: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

So:So:

Core ML polymorphism can be encodedusing parameterized classes alone

Page 11: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

Polymorphic virtual methodsPolymorphic virtual methods Define an interface or abstract class:Define an interface or abstract class:

interface Sorter { void Sort<T>(T[] a, IComparer<T> c); }interface Sorter { void Sort<T>(T[] a, IComparer<T> c); }

Implement the interface:Implement the interface:

class QuickSort : Sorter { ... }class QuickSort : Sorter { ... }class MergeSort : Sorter { ... }class MergeSort : Sorter { ... }

Use instances at many type instantiations:Use instances at many type instantiations:

void TestSorter(Sorter s, int[] ia, string[] sa) {void TestSorter(Sorter s, int[] ia, string[] sa) { s.Sort<int>(ia, IntComparer); s.Sort<int>(ia, IntComparer); s.Sort<string>(sa, StringComparer); s.Sort<string>(sa, StringComparer);}}

TestSorter(new QuickSort(), ...);TestSorter(new QuickSort(), ...);TestSorter(new MergeSort(), ...);TestSorter(new MergeSort(), ...);

Page 12: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

Compare:Compare: Define an SML signature:Define an SML signature:

signature Sorter = sig signature Sorter = sig val Sort : ‘a array * (‘a*’a->order) –> unit val Sort : ‘a array * (‘a*’a->order) –> unit endend

Define structures that match the signature:Define structures that match the signature:

structure QuickSort :> Sorter = ... structure QuickSort :> Sorter = ... structure MergeSort :> Sorter = ... structure MergeSort :> Sorter = ...

Use structures at many type instantiations:Use structures at many type instantiations:

functor TestSorter(S : Sorter) = structfunctor TestSorter(S : Sorter) = struct fun test (ia, sa) = fun test (ia, sa) = (S.Sort(ia, Int.compare); (S.Sort(ia, Int.compare); S.Sort(sa, String.compare) S.Sort(sa, String.compare) endend

structure TestQuickSort = TestSorter(QuickSort); structure TestQuickSort = TestSorter(QuickSort); TestQuickSort.test(...);TestQuickSort.test(...);structure TestMergeSort = TestSorter(MergeSort); structure TestMergeSort = TestSorter(MergeSort); TestMergeSort.test(...);TestMergeSort.test(...);

Page 13: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

Or (Russo first-class Or (Russo first-class modules):modules):

Define an SML signature:Define an SML signature:

signature Sorter = sig signature Sorter = sig val Sort : ‘a array * (‘a*’a->order) –> unit val Sort : ‘a array * (‘a*’a->order) –> unit endend

Define structures that match the signature:Define structures that match the signature:

structure QuickSort :> Sorter = ... structure QuickSort :> Sorter = ... structure MergeSort :> Sorter = ... structure MergeSort :> Sorter = ...

Use a Use a functionfunction to test the structures: to test the structures:

fun TestSorter (s, ia, sa) = fun TestSorter (s, ia, sa) = let structure S as Sorter = s in let structure S as Sorter = s in (S.Sort(ia, Int.compare); (S.Sort(ia, Int.compare); S.Sort(sa, String.compare)) S.Sort(sa, String.compare)) end end

TestSorter ([structure QuickSort as Sorter], ...);TestSorter ([structure QuickSort as Sorter], ...);TestSorter ([structure MergeSort as Sorter], ...);TestSorter ([structure MergeSort as Sorter], ...);

Page 14: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

Question:Question:

Can System F “first-class Can System F “first-class polymorphism” polymorphism”

be encoded using be encoded using polymorphic virtual methodspolymorphic virtual methods

??

Page 15: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

To answer the question...To answer the question...

Take System F + recursion + call-by-value Take System F + recursion + call-by-value evaluation orderevaluation order

Formalize a type-preserving translation Formalize a type-preserving translation into Generic C#into Generic C#

Prove that it worksProve that it works

Page 16: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

In more detailIn more detail

Source is System F + CBV recursion:Source is System F + CBV recursion:

(Types) A,B ::= X | A -> B | forall (Types) A,B ::= X | A -> B | forall X.AX.A(Terms) M,N ::= x | M N | rec y(x:A):B.M | M A | (Terms) M,N ::= x | M N | rec y(x:A):B.M | M A | ΛΛX.VX.V(Values) V ::= rec y(x:A):B.M | (Values) V ::= rec y(x:A):B.M | ΛΛX.VX.V

Target is “C# minor”Target is “C# minor” a tiny, purely functional subset of Generic C#a tiny, purely functional subset of Generic C# very similar to Featherweight Java (Pierce, very similar to Featherweight Java (Pierce,

Igarashi, Wadler)Igarashi, Wadler) includes just enough for our translation plus a includes just enough for our translation plus a

bit more (run-time types)bit more (run-time types)

Page 17: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

Translation: functionsTranslation: functions Represent function types using a parameterized class:Represent function types using a parameterized class:

class Arrow<X,Y> {class Arrow<X,Y> { public virtual Y app(X x); public virtual Y app(X x); }}

Function application is just invocation of app methodFunction application is just invocation of app method Represent function values by instances of “closure classes” Represent function values by instances of “closure classes”

implementing Arrow e.g. implementing Arrow e.g. λλx:X->Y.x yx:X->Y.x y translates to translates to new new C<X,Y>(y)C<X,Y>(y) with with

class C<X,Y> : Arrow<Arrow<X,Y>,Y> {class C<X,Y> : Arrow<Arrow<X,Y>,Y> { X y; X y; public override Y app(Arrow<X,Y> x) { public override Y app(Arrow<X,Y> x) { return x.app(this.y); return x.app(this.y); } }}}

Note:Note: fields store free variables of functionfields store free variables of function class is parameterized over free class is parameterized over free typetype variables of function variables of function

Page 18: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

Translation: recursionTranslation: recursion

Translate recursion into self-reference through Translate recursion into self-reference through thisthis

For example, For example, rec y(x:X):X. y(x)rec y(x:X):X. y(x) translates to translates to new new

C<X>()C<X>() with with

class C<X> : Arrow<X,X> {class C<X> : Arrow<X,X> { public override X app(X x) { public override X app(X x) { return this.app(x); return this.app(x); } }}}

Page 19: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

Translation: polymorphismTranslation: polymorphism

We can’t use a single class definition for “forall” We can’t use a single class definition for “forall” typestypes

Instead use different class for each such typeInstead use different class for each such typee.g. e.g. forall X. X->Yforall X. X->Y is is

class ForAll_X_XtoY<Y> {class ForAll_X_XtoY<Y> { public virtual Arrow<X,Y> tyapp<X>(); public virtual Arrow<X,Y> tyapp<X>();}}

Type application is just invocation of tyapp methodType application is just invocation of tyapp method Represent polymorphic values by instances of Represent polymorphic values by instances of

“closure classes” implementing appropriate ForAll “closure classes” implementing appropriate ForAll classclass close over free variables and free type variables just as close over free variables and free type variables just as

with functionswith functions

Page 20: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

Translation: polymorphism, Translation: polymorphism, cont.cont.

Problem: translation of types doesn’t commute Problem: translation of types doesn’t commute with substitution i.e.with substitution i.e.([A/X]B)* ≠ [A*/X]B*([A/X]B)* ≠ [A*/X]B*

Example:Example: forall X.X->Yforall X.X->Y translates to translates to All_X_XtoY<Y>All_X_XtoY<Y> Now substitute Now substitute forall Z.Zforall Z.Z for for YY We get We get forall X.(X->forall Z.Z) forall X.(X->forall Z.Z) which translates to which translates to

All_X_XtoAll_Z_ZAll_X_XtoAll_Z_Z Solution (LSolution (Lääufer & Odersky): use a single class to ufer & Odersky): use a single class to

represent a whole represent a whole familyfamily of related polymorphic of related polymorphic typestypes

Page 21: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

Properties of translationProperties of translation

Fully type-preserving:Fully type-preserving:A* = B* iff A=BA* = B* iff A=B

Translation preserves types of terms:Translation preserves types of terms:If M:A translates to e then e:A*If M:A translates to e then e:A*

Translation preserves convergence Translation preserves convergence behaviour of closed terms (i.e. the behaviour of closed terms (i.e. the translation is “adequate”):translation is “adequate”):

If M:A translates to e If M:A translates to e then M converges iff e converges then M converges iff e converges

Page 22: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

ObservationsObservations

Strictly speaking the translation is not Strictly speaking the translation is not compositional (global generation of names for compositional (global generation of names for forall types)forall types)

The translation is harnessing the power of The translation is harnessing the power of polymorphic virtual methodspolymorphic virtual methods Generic C#, GJ, NextGen permit polymorphic methods to Generic C#, GJ, NextGen permit polymorphic methods to

be virtualbe virtual Eiffel, C++ do notEiffel, C++ do not

Distinctiveness of polymorphic virtual methods Distinctiveness of polymorphic virtual methods shows up in (type-preserving) implementationsshows up in (type-preserving) implementations requires execution-time type applicationrequires execution-time type application

Page 23: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

Future workFuture work

Proof of semantic correctness (adequacy) of Proof of semantic correctness (adequacy) of translationtranslation use method of logical relationsuse method of logical relations Harper, Morrisett, Minamide use similar technique to Harper, Morrisett, Minamide use similar technique to

prove correctness of typed closure conversionprove correctness of typed closure conversion But: we have impredicative polymorphism and recursion; But: we have impredicative polymorphism and recursion;

this makes things trickythis makes things tricky Compositional, partial type-preserving translationsCompositional, partial type-preserving translations FFωω

Dynamic typesDynamic types Power of nominal vs structural equivalence of Power of nominal vs structural equivalence of

typestypes

Page 24: Transposing F to C Transposing F to C Andrew Kennedy & Don Syme Microsoft Research Cambridge, U.K

Questions?Questions?