You are on page 1of 23

1

Theorems for Free for Free


Parametricity, With and Without Types

AMAL AHMED, Northeastern University


DUSTIN JAMNER, Northeastern University
JEREMY SIEK, Indiana University
PHILIP WADLER, University of Edinburgh

The polymorphic blame calculus integrates static typing, including universal types, with dynamic typing. The primary challenge
with this integration is preserving parametricity: even dynamically-typed code should satisfy it once it has been cast to a universal
type. Ahmed et al. (2011) employ runtime type generation in the polymorphic blame calculus to preserve parametricity, but a
proof that it does so has been elusive. Matthews and Ahmed (2008) gave a proof of parametricity for a closely related system
that combines ML and Scheme, but later found a �aw in their proof. In this paper we prove that the polymorphic blame calculus
satis�es relational parametricity. The proof relies on a step-indexed Kripke logical relation. The step-indexing is required to make
the logical relation well-de�ned in the case for the dynamic type. The possible worlds include the mapping of generated type
names to their concrete types and the mapping of type names to relations. We prove the Fundamental Property of this logical
relation and that it is sound with respect to contextual equivalence. To demonstrate the utility of parametricity in the polymorphic
blame calculus, we derive two free theorems.
CCS Concepts: •Software and its engineering ! General programming languages; •Social and professional topics !
History of programming languages;

Additional Key Words and Phrases: keyword1, keyword2, keyword3


ACM Reference format:
Amal Ahmed, Dustin Jamner, Jeremy Siek, and Philip Wadler. 2017. Theorems for Free for Free. PACM Progr. Lang. 1, 1, Article 1
(January 2017), 23 pages.
DOI: 10.1145/nnnnnnn.nnnnnnn

1 INTRODUCTION
The last decade has delivered considerable progress regarding the integration of static and dynamic typing, both in
theory and in practice. On the practical side, languages such as TypeScript (Bierman et al. 2014; Hejlsberg 2012),
Hack (Verlaguet 2013), Flow (Chaudhuri 2014), Dart (Bracha 2011), and C# (Hejlsberg 2010) combine elements of
static and dynamic typing. Over a million lines of TypeScript code went into the Microsoft Azure portal (Turner 2014).
On the theory side, in the last decade researchers have studied gradual typing (Allende et al. 2013; Gronski et al. 2006;
Ina and Igarashi 2011; Siek and Taha 2006; Swamy et al. 2014), multi-language integration (Matthews and Findler 2007;
Tobin-Hochstadt and Felleisen 2006), the blame calculus (Wadler and Findler 2009), and manifest contracts (Greenberg
et al. 2010). In fact, this area of research has a long history, including the dynamic type of Abadi et al. (1991), the
quasi-static types of Thatte (1990), the coercions of Henglein (1994), the contracts of Findler and Felleisen (2002), and
the dynamic dependent types of Ou et al. (2004).
The integration of dynamic typing with languages that include polymorphism (i.e., type abstraction) is particularly
delicate. Abadi et al. (1991) remark that their typecase construct for eliminating values of type Dynamic could be
used to violate type abstraction and suggest static restrictions to prevent that. Leroy and Mauny (1991) implemented
this approach in CAML as well as a non-parametric approach. A few years later, Abadi et al. (1995) allude to using
runtime type generation (RTG) as a mechanism for protecting abstraction. Indeed, Sewell (2001) uses RTG to protect
abstractions in distributed systems and Rossberg (2003, 2006) uses RTG for safe dynamic linking. Rossberg (2003)
proves an Opacity Theorem, showing that substitution of di�erent values at abstract type does not a�ect reduction.

with paper note.


2017. 2475-1421/2017/1-ART1 $15.00
DOI: 10.1145/nnnnnnn.nnnnnnn

PACM Progr. Lang., Vol. 1, No. 1, Article 1. Publication date: January 2017.
The strongest correctness criteria regarding the protection of type abstractions is relational parametricity (Reynolds
1983). The idea is expressed in terms of a type-indexed relation, a logical relation, that captures when two expressions
exhibit the same behavior when viewed at a particular type. Consider the following traditional example (Pitts 1998a)

(0, ( (x : int ). 1 x ), ( (x : int ). x = 0)) vs. (1, ( (x : int ). 1 x ), ( (x : int ). x = 1))

each of which may be given either of the types

int ⇥ (int ! int ) ⇥ (int ! bool ) vs. 9X .X ⇥ (X ! X ) ⇥ (X ! bool ).

The two expressions di�er when assigned the �rst type, but behave identically when assigned the second type. In
this example, to prove equivalence one would choose the relation R = {(0, 1), (1, 0)} for X . The Abstraction Theorem
of Reynolds (1983) proves that the polymorphic lambda calculus preserves its type abstractions by way of showing
that every well-typed expression is related to itself in the logical relation. This kind of theorem is now referred to as
the Fundamental Property of a logical relation.
Matthews and Ahmed (2008) studied the integration of Scheme and ML, using RTG to protect ML’s polymorphic
functions from the runtime type tests—e.g., checking whether a given value is an integer, a Boolean, or a function—
common to dynamic languages like Scheme. For their ML+Scheme multi-language, they de�ned a step-indexed
logical relation indexed by ML types and a dynamic type (TST, the Scheme type) and presented a proof of the
Fundamental Property for the multi-language. Unfortunately, they later discovered a �aw in the proof. Ahmed, Kuper,
and Matthews (2011) �xed this proof by introducing possible worlds that map type variables to the generated type
names, concrete types, and relations to use when relating values at the abstract type. This line of work was put on
hold but an unpublished manuscript is available (Ahmed et al. 2011b).
Neis et al. (2011) study G, a polymorphic language extended with Girard’s J operator but without the type Dynamic.
The J operator is a non-parametric cast that tests for type equality at runtime, after abstract types have been replaced
by their concrete type. Neis et al. (2011) de�ne a Kripke logical relation, with some similarities to the one we use here,
that supports reasoning about program equivalence and they prove the Fundamental Property. This logical relation,
however, does not ensure that expressions of polymorphic type behave parametrically. It instead associates parametric
behavior with type names that result from RTG. However, they show that parametric behavior can be obtained by
wrapping expressions in a type-directed manner with appropriate uses of RTG. We have investigated whether a
polymorphic language with the dynamic type could be compiled to G in a way that would ensure parametricity
(using recursive types to encode the dynamic type), but it seems that the results in Neis et al. (2011) are not general
enough to make this possible. Nevertheless, more investigation woud be helpful to clarify the relationship between
the polymorphic blame calculus and G.
In this paper we pick up where Ahmed et al. (2011b) left o�, but relocate to the more general setting of the
polymorphic blame calculus ( B) of Ahmed et al. (2011a). The relocation came with many technical changes at the
heart of the semantics and logical relation, including the mechanics of type application and run-time type generation.
The B calculus combines the polymorphic lambda calculus of Girard (1972) and Reynolds (1974) with the blame
calculus of Wadler and Findler (2009) (minus re�nement types). In Section 2 we review these three calculi and
make some adjustments to the polymophic blame calculus, some motivated by parametricity, some to simplify the
calculus. We give the formal de�nition of the polymophic blame calculus in Section 3. With the stage set, Section 4
de�nes a Kripke logical relation, proves the Fundamental Property, and proves soundness with respect to contextual
equivalence. To demonstrate the utility of our logical relation, in Section 5 we derive “free theorems” in the tradition
of Wadler (1989). We prove a theorem about the K combinator and a theorem about how functions that rearrange
their input commute with the map function.
To summarize, this paper makes the following technical contributions.
• A polymorphic blame calculus ( B) that enables a natural notion of parametricity (Sections 2.4 and 3).
• The de�nition of a Kripke logical relation for B for program equivalence and parametricity (Section 4.2).
• A proof of the Fundamental Property (Section 4.3).
• A proof of Soundness with respect to Contextual Equivalence (Section 4.3).
• Two examples of free theorems derived from our parametricity result (Section 5).
The complete de�nitions and proofs are in the supplementary material. We explain the relationship between this
result and those in the literature in Section 6. We discuss further research and conclude in Section 7.

2
2 THE ROAD TO POLYMORPHIC BLAME
The polymorphic blame calculus combines the polymorphic lambda calculus (Girard 1972; Reynolds 1974) with the
blame calculus (Wadler and Findler 2009). We review the polymorphic lambda calculus and its notion of parametricity
in subsection 2.1. We review the blame calculus, and how it integrates typed and untyped languages using casts and
the dynamic type, in subsection 2.2. We then review the design considerations in prior versions of polymorphic blame
calculus of Ahmed et al. (2011a) and Siek and Wadler (2017), and discuss one more design change to better support
parametricity.

2.1 Review of the Polymorphic Lambda Calculus and Parametricity


The polymorphic lambda calculus ( F) extends the lambda calculus to capture the essence of generics. That is, it
enables code to be reused on data of di�erent types. F adds two language constructs to simply-typed lambda calculus:
type abstraction ⇤X .e and type application e [B]. Type abstraction parameterizes an expression e with respect to
type variable X . Values of type X may �ow through the expression e but e may not manipulate those values in a way
that depends on their actual type. A simple example of a type abstraction is the swap function that exchanges the
two elements of a pair:
swap : 8X . 8Y . X ⇥Y ! Y ⇥X
swap = ⇤X .⇤Y . (p : X ⇥Y ). (snd(p), fst(p))
A type abstraction ⇤X .e has polymorphic (or universal) type, written 8X . A, meaning that e has type A for any type
X . One can nest type abstractions, as in swap above, to parameterize over multiple types.
Type application e [B] enables the use of a type abstraction (the result of e) by instantiating its type variable at
type B. To swap a pair of an integer and a bool, we �rst apply swap to int and to bool and then apply the result to the
pair. We swap back similarly.
swap [int ] [bool ] (1, true ) !⇤ (true, 1)
swap [bool ] [int] (true, 1) !⇤ (1, true )
The following example is rejected by the type system of F because it tries to add the elements of the pair, which
would depend on both elements having type int.
bad = ⇤X .⇤Y . (p : X ⇥Y ). fst(p) + snd(p)
In return for this restriction on type abstractions, F provides a reasoning principle called relational parametricity
(Reynolds 1983), for establishing when two expressions of the same type A have identical behavior, which is expressed
in terms of a logical relation. Figure 1 de�nes the logical relation for F, consisting of a relation E JAK over pairs
of expressions, and an auxiliary relation V JAK over pairs of values; both relations take as an extra argument, an
environment mapping type variables to relations. Relation E JAK holds when two expressions behave the same:
when they both evaluate to values that behave the same according to relation V JAK. The relations on values is
de�ned by induction on the type. For integers and Booleans, it requires the two values to be literally the same. For
two pairs of type A ⇥ B, the �rst elements must behave the same and the second elements must behave the same. For
two functions of type A ! B to behave the same, they are only required to produce outputs related at B when given
inputs related at A. (There need not be any syntactic similarity between the two functions.) For two type abstractions
of type 8X . A to behave the same, their instantiations must behave the same. However, because the two abstractions
do not manipulate values of type X , it is not required that the values at type X behave the same. Instead, they can be
related according to any arbitrary relation R! The reason for the mapping now becomes apparent, it maps each
type variable X to a relation R that says how values at type X are related. Dually, for two existential packages to be
related at type 9X . A, there must exist some relation R such that the packed values 1 and 2 are related at type A
under an environment extended with X bound to R.
The Abstraction Theorem of Reynolds (1983) (aka. Fundamental Property, aka. Parametricity) says that every
well-typed expression e of F behaves the same as itself according to its type A, that is, (e, e) 2 E JAK . At �rst glance
this is underwhelming, of course e behaves the same as itself! The powerful part is that e behaves “according to its
type A”. It is powerful enough to provide behavioral guarantees, which Wadler (1989) christened theorems for free.
Consider again the swap function of type 8X . 8Y . X ⇥Y ! Y ⇥X . It turns out that a free theorem completely
determines the output of swap and any other function with the same type.

3
E JAK = {(e 1 , e 2 ) | 9 1 , 2 . e1 !⇤ 1 and e 2 !⇤ 2 and ( 1 , 2) 2 V JAK }
V JintK = {(n, n) | n 2 Z}
V Jbool K = {(b, b) | b 2 B}
V JA ⇥ BK = {(p1 , p2 ) | (fst(p1 ), fst(p2 )) 2 E JAK and (snd(p1 ), snd(p2 )) 2 E JAK }
V JA ! BK = {( f , ) | 8( 1 , 2) 2 V JAK . ( f 1, 2) 2 E JBK }
V J8X . AK = {( 1 , 2) | 8B 1 , B 2 , R ✓ B 1 ⇥ B 2 . ( 1 [B 1 ], 2 [B 2 ]) 2 E JAK (X :=R)}
V J9X . AK = {(pack(B 1 , 1 ), pack(B 2 , 2 )) | 9R ✓ B 1 ⇥ B 2 . ( 1 , 2) 2 V JAK (X :=R)}
V JX K = (X )

Fig. 1. A Logical Relation for F.

T������ 2.1. (A Free Theorem of 8X . 8Y . X ⇥Y ! Y ⇥X )


Suppose e is any expression of type 8X . 8Y . X ⇥Y ! Y ⇥X . Let A and B be arbitrary types. For any 1 of type A and 2 of
type B,
e [A] [B] ( 1 , 2) !⇤ ( 2 , 1)

Proof
By the Fundamental Property, we have (e, e) 2 E J8X . 8Y . X ⇥Y ! Y ⇥X K. Choose R 1 = {( 1 , 1 )} and
R 2 = {( 2 , 2 )}. Let e AB = e [A] [B]. So we have
(e AB , e AB ) 2 E JX ⇥Y ! Y ⇥X K (X :=R 1 , Y :=R 2 )
Note that the input ( 1 , 2) is related to itself at X ⇥ Y
(( 1 , 2 ), ( 1 , 2 )) 2 V JX ⇥ Y K (X :=R 1 , Y :=R 2 )
so the outputs of e AB are related at type Y ⇥ X .
(e AB ( 1 , 2 ), e AB ( 1, 2 )) 2 E JY ⇥X K (X :=R 1 , Y :=R 2 )
Thus, the two copies of e A ( 1 , 2) reduce to some pairs p1 and p2 related at Y ⇥ X .
e AB ( 1 , 2) !⇤ p 1 e AB ( 1 , 2) !⇤ p 2 (p1 , p2 ) 2 E JY ⇥X K (X :=R 1 , Y :=R 2 )
Let p1 = ( 11 , 12 ) and p2 = ( 21 , 22 ). We have 11 and 21 related at Y , therefore ( 11 , 21 ) 2 R 2 . Which
means that 11 = 21 = 2 . Similar, we have 12 and 22 related at X , therefore ( 12 , 22 ) 2 R 1 . Which means
that 12 = 22 = 1 . Thus, we have shown that e [A] [A] ( 1 , 2 ) !⇤ ( 2 , 1 ). ⇤
If we had chosen a weaker polymorphic type we would have obtained a weaker theorem. For example, if we had
chosen the type 8X . X ⇥X ! X ⇥X , then the free theorem would be e [A] [A] ( 1 , 2 ) !⇤ ( 3 , 4 ) for some 3 , 4
where 3 2 { 1 , 2 } and 4 2 { 1 , 2 }.

2.2 Review of the Blame Calculus


The blame calculus de�nes interaction between a typed and untyped lambda calculus. It introduces a dynamic type ?
to characterize expressions of statically unknown type and one language construct: the cast
p
(e : A =) B)
which checks whether the value produced by e has type B. If not, it ascribes fault to the blame label p. We abbreviate
a sequence of casts in the obvious way,
p q def p q
e : A =) B =) C = (e : A =) B) : B =) C

4
One scenario is that a programmer begins with untyped code and then adds types. Here is a program assembling
untyped components. Untyped code is surrounded by ceiling brackets, d·e.
let inc? = d (x ). x + 1e in
let two? = d ( f ). (x ). f ( f x )e in
dtwo? inc? 0e
It evaluates to d2e : ?.
Following a slogan of Dana Scott (Harper 2013; Statman 1991) we treat “untyped as unityped”: untyped code is
typed code where every term has the dynamic type ?. By convention, we append ? to the name of untyped functions
to distinguish them from their typed counterpart.
It is trivial to rewrite a three-line program to have types, but we wish to add types gradually: our technique should
work as well when each one-line de�nition is replaced by a thousand-line module. We use casts to manage the
transition between typed and untyped code.
Here is our program again but we add types to the two component and insert a cast from its type to ?.
let inc? = d (x ). x + 1e in
let two = ( X . ( f :X !X ). (x:X ). f ( f x )) in
+` (1)
let two? = (two : 8X .(X !X )!X !X =) ?) in
dtwo? inc? 0e
It evaluates to d2e : ?. If in (1) we replace
dtwo? inc? 0e by dtwo? 0 inc? e (2)
it now evaluates to blame `. Blaming ` indicates fault lies with the context containing the cast. The positive and
negative blame labels, +` and `, correspond to p and p̄, respectively, in prior blame calculi (Ahmed et al. 2011a). The
above example demonstrates an important bene�t of casts and blame tracking: the fault lies at the boundary between
the typed and untyped code, providing encapsulation for the typed code.
Conversely, here is the program mostly typed, with two? the only untyped component, cast from ? to its type.
let inc = ( (x:int ). x + 1) in
let two? = d ( f ). (x ). f ( f x )e in
+` (3)
let two = (two? : ? =) 8X .(X !X )!X !X ) in
two int inc 0
It evaluates to 2 : int . If in (3) we replace
d ( f ). (x ). f ( f x )e by d ( f ). (x ). 2e (4)
it now evaluates to blame +`. Blaming +` indicates fault lies with the term contained in the cast.
Untyped lambda calculus is de�ned by embedding into blame calculus. For example, d (x ). x + 1e is equivalent to
+m +n +o
( (x : ?). ((x : ? =) int ) + 1) : int =) ?) : ?!? =) ?
where m, n, o are fresh blame labels.
Casting an int to ? and back to int acts as the identity.
+` +m
2 : int =) ? =) int ! 2
On the other hand, casting the integer to a function raises blame.
+` +m
2 : int =) ? =) (int!int ) ! blame +m
A cast that yields a function reduces to two casts, one contravariant on the domain and one covariant on the range.
+`
(d (x ). x + 1e : ? =) int!int ) 2
` +`
!⇤ ( (x:?). dx + 1e) (2 : int =) ?) : ? =) int

!⇤ d3e

5
The blame label is negated on the contravariant cast.

2.3 Prior Work on Polymorphic Blame


The polymorphic blame calculus of Ahmed et al. (2011a) seeks to integrate the type ? and casts of the blame calculus
into F without sacri�cing parametricity. To see why this is challenging, consider the following variation on the swap
function. It casts a dynamically typed function to one which has the type of the swap function. The dynamically
typed function has no restrictions enforced by its type; we choose it to be the identity function.
+`
badSwap = d (x ). xe : ? =) (8X .8Y .X ⇥ Y ! Y ⇥ X )

First, note that the polymorphic blame calculus does not reject this badSwap statically because it allows casts from
any type to ? and from ? to any type, which is needed to accommodate interactions with untyped code. So we turn
to the dynamic behavior of badSwap. Given its type, parametricity tells us that if we instantiate it at int twice and
apply it to (1, 2), the result, if there is one, should be (2, 1). Let’s see what happens if we evaluate badSwap by simply
combining the reduction rules of F and the blame calculus, assuming that we can simply replace the type variables
X and Y by their instantiations int.

badSwap[int][int ](1, 2)
` +`
!⇤ (( (x : ?). x )((1, 2) : int ⇥ int =) ?)) : ? =) int ⇥ int
` +`
!⇤ ((1, 2) : int ⇥ int =) ?) : ? =) int ⇥ int
` +` ` +`
!⇤ (((1 : int =) ?) : ? =) int ), ((2 : int =) ?) : ? =) int ))
!⇤ (1, 2)

This answer is wrong! It violates the Fundamental Property—which guarantees parametric behavior—for the type of
badswap, namely 8X .8Y .X ⇥ Y ! Y ⇥ X . We would prefer the program to halt with an error, blaming the cast with
label +`.
The fundamental problem is that in F, type application is accomplished by substitution, with the reduction rule

(⇤X .e) [B] ! e[B/X ]

In the badSwap example, the distinction between the type variables X and Y was erased when they were both replaced
by int . Ahmed et al. (2011a) solve this problem by delaying the substitution, using a binder and a conversion
operator that replaces a -bound type variable with its binding (called a static cast in that paper).
+X
(⇤X . ) [B] ! X :=B. ( : A =) A[X :=B]) if ` ⇤X . : 8X .A

With that change, badSwap halts with an error when it fails to cast from X to ? to Y , because X , Y .

badSwap[int ][int ](1, 2)


X ` +` Y ` +`
!⇤ X :=int . Y :=int . (((1 : int =) X =) ?) : ? =) Y ), ((2 : int =) Y =) ?) : ? =) X ))
!⇤ blame +`

Ahmed et al. (2011a) conjecture that this design ensures parametricity, but they did not formulate a logical relation
for the polymorphic blame calculus nor prove the Fundamental Property 1 .
Regardless of parametricity, Siek and Wadler (2017) point out that the design of Ahmed et al. (2011a) is ‘topsy
turvy’ in that it evaluates things one might expect to be values, and leaves as values things one might expect to be
evaluated. In particular, following Wright (1995) and Pitts (1998b), one might expect the bodies of type abstractions to
be restricted to values. Ahmed et al. (2011a) mention that this would be desirable, but it is impossible in their system

1 Ahmed et al. (2009) prove blame and subtyping theorems for a polymorphic blame calculus. Ahmed et al. (2011a) present a proof of a stronger
subtyping theorem based on the jack-of-all-trades property, but unfortunately that proof was �awed (Ahmed et al. 2014).

6
due to their formulation of reductions for casts:
p p p
: A!B =) A0!B 0 ! (x:A0 ). (x : A0 =) A) : B =) B 0 (5)
p p
: A =) 8X .B ! X . ( : A =) B) (6)
The right-hand side of the second rule is a type abstraction with a body that is an arbitrary cast, and hence not a
value. One might take any type abstraction to be a value, regardless of whether its body is a value, but this would lead
to a violation of parametricity. For instance, parametricity requires that there should be no values of type 8X .X , but
the term X . blame +` has that type! To avoid the problem, they require evaluation underneath type abstractions.
That in turn leads to a problem with binders, so instead of generating new names globally, they push binders
inside of values:
X :=A. ( :B). e ! ( :B[X :=A]). X :=A. e (7)
X :=A. X . ! X . X :=A. (8)
Rule 7 causes binders to be retained in function values, where one might expect the binder to be evaluated
immediately.
Siek and Wadler (2017) propose a simple way to avoid these convolutions, taking inspiration from the alternate
approach to function casts that can be made space-e�cient (Siek and Wadler 2010). In that approach, casts between
function type are values and the following reduction rule handles the application of a cast-wrapped function.
p p p
( : A!B =) A0!B 0 ) 0
! ( 0
: A0 =) A) : B =) B 0 (9)
p
The same approach can be applied to polymorphic values. Declare casts of the form ( : A =) 8X .B) to be values
and add a reduction rule for applying a cast-wrapped polymorphic value. Also, instead of inserting binders during
evaluation, Siek and Wadler (2017) insert them during compilation, turning every type application into a combination
of -binder and type application:
def
e [B] = ( :=B. e [ ])
So their reduction rules for instantiating polymorphic values are as follows.
( X . ) [ ] ! [ /X ] (10)
p p
( : A =) 8X .B) [ ] ! : A =) B[ /X ] (11)
In place of abstraction on the right-hand side of reduction rule (6), here in reduction rule (11) we have application
on the left-hand side. Reductions no longer insert casts inside of type abstractions so their bodies can be restricted
to values, as desired. This rules out any need to evaluate under type abstractions. In particular, X . blame +` is no
longer a valid term, since blame +` is not a value.

2.4 Replacing with Type Generation At Type Application


The �nal twist in the story came as we developed the logical relation for the design of Siek and Wadler (2017). The
compilation step that inserts binders complicates reasoning about parametricity. We discovered that the intermediate
language with binders is not parametric in the usual sense because one can use the same binder with two or more
type applications. For example, one can observe non-parametric behavior of badSwap by instantiating it twice with
the same .
:=int . badSwap [ ] [ ] (1, 2) !⇤ (1, 2)
Such examples don’t happen at the source level because the compilation step uses each -bound name in exactly one
type application. However, capturing this invariant in the intermediate language would signi�cantly complicate its
type system. This disconnect between the name generation and type application also shows up in the logical relation.
Instead of a forall-quanti�ed relation R appearing in the de�nition of V J8X .AK, the R’s are instead associated with
-generated names, as in Neis et al. (2011).
To regain a strong notion parametricity, we elect to generate fresh names when reducing a type application and
immediately place the names in a global store, forgoing the use of binders. Thanks to the changes described above
regarding casted type abstractions, using a global store is straightforward. Let range over name stores whose entries

7
Convertibility Labels ::= + |
Compatibility Labels p, q ::= +` | `
Base Types ::= int | bool
Types A, B, C ::= | A ⇥ B | A ! B | 8X . A | X | | ?
Ground Types G,H ::= | ? ⇥ ? | ?! ? |
Operations ~ ::= + | | ⇤ | ...
Expressions e ::= n | true | false | if e then e else e | e ~ e | x | (x : A ). e | e e | ⇤X .v |
p
e [B] | he ,e i | 1 e | 2 e | (e : A =) B ) | (e : A =) B ) | blame p
Values v ::= n | true | false | (x : A ). e | ⇤X .v | hv ,v i | (v : A ! B =) A 0 ! B 0 ) |
p
(v : 8X . A =) 8X . B ) | (v : A =) ) | (v : A ! B =) A 0 ! B 0 ) |
p p
(v : A =) 8X . B ) | (v : G =) ?)
Type-Name Stores Σ ::= · | Σ , :=A
Type Environments ∆ ::= · | ∆, X
Environments Γ ::= · | Γ, x : A
Evaluation Contexts E ::= [·] | E ~ e | v ~ E | if E then e else e | E e | v E | E [A] | hE,ei | h ,Ei |
p
(E : A =) B ) | (E : A =) B )

Fig. 2. Syntax

take the form :=B and write . e for a con�guration that pairs a name store with an expression. Then we replace
(10) and (11) with the following rules.
+
. ( X . ) [B] ! , :=B . [ /X ] : A[ /X ] =) A[B/X ] (12)
p p +
. ( : A =) 8X .A0 ) [B] ! , :=B . : A =) A0[ /X ] =) A0[B/X ] (13)

3 POLYMORPHIC BLAME CALCULUS


Now that we solved these design challenges, we can proceed with the formal presentation of the polymorphic blame
calculus ( B). The syntax is de�ned in Figure 2. Let A, B, C range over types, which are either base types , pair types
A ⇥ B, function types A ! B, universal types 8X .B, type variables X , type names , or the dynamic type ?. Let
include integers int and Booleans bool . We do not include existential types, as they can be encoded with universal
types. The ground types are those types that can be directly injected into type ?, and include the base types, the
function type ? ! ?, the pair type ? ⇥ ?, and type names . The other types can be cast to ?, but such casts factor
through the ground types. Let e range over expressions, which are either integers n, the Booleans true and false,
variables x, operator applications e ~ e, function abstraction (x:A). e, function application e 1 e 2 , type abstraction
p
X . , type application e [A], pairs he ,e i, projections 1 e and 2 e , casts (e : A =) B), conversions (e : A =) B), or
errors blame p. The body of a type abstraction must be a value.
The conversion form (e : A =) B) is used to make explicit the conversion between a type name and the type it is
bound to (in ). Let range over conversion labels of the form + or .
Let range over values, which include integers, Booleans, function abstractions, pairs of values, and type abstrac-
tions. A value whose type is a name is a conversion of the form ( : A =) ). In addition, conversions and casts to a
function or a universal type are values, which reduce when applied to a value or type, respectively.
We write B[A/X ] (or B[A/ ]) for the capture-avoiding substitution of type A for X (or ) in type B.
We abbreviate a sequence of conversions in the same way as casts,
0 0
def
e : A =) B =) C = (e : A =) B) : B =) C.
and similarly for combinations of casts and conversions.
3.0.1 Static Semantics. The static semantics for types is de�ned in Figure 3. Let range over type variable contexts,
which are lists of X ’s. Let range over name stores, which are lists of binding of type names to types :=A. Write

8
` to indicate that is a well-formed name store and ; ` for well-formed type context. Write ; ` A for
well-formed types.
Write ; ` A B to indicate that in context ; types A and B are convertible under . Conversions must be
between convertible types, and the rules for convertibility ensure that reductions involving conversions preserve
convertibility. That is, when a conversion (e : A =) B) occurs on the right-hand side of a reduction rule, we can
deduce that ; ` A B from the fact that the conversions of the left-hand side of the rule were well typed. If
:=A 2 , judgments ; ` B + C and ; ` C B hold i� C = B[A/ ]. Further, ; ` A B i� ; ` B A.
Write < if is not + or . Convertability is almost re�exive: in that ; ` A A if < for every free name
in A. Figure 3 de�nes a negation operator that �ips the sign of a conversion label.
Write ; ` A B to indicate that in context ; types A and B are compatible. The intuition is that two types are
compatible if it is possible for a cast from one to the other to succeed. The type ? is compatible with any type (on
either side). A universal type 8X .A is compatible with a type B if instantiating it with ? yields a compatible type,
that is, if A[?/X ] is compatible with B. On the other hand, a type A is compatible with a universal type 8X .B if A is
compatible with B while holding X abstract, that is, if ; , X ` A B. The compatibility relation is re�exive but not
symmetric because of the treatment of universal types. The rules for compatibility ensure that reductions involving
casts preserve compatibility.
The static semantics for expressions is de�ned in Figure 4. Let range over type context, which are lists of
hypotheses of the form x:A. Write ; ; ` e : A to indicate that in context ; ; expression e has type A. Typing for
constants, operators, function abstraction, function application, type abstraction, and type application is standard. A
p
conversion (e : A =) B) has type B if expression e has type A and ; ` A B. Similarly, a cast (e : A =) B) has
type B if expression e has type A and ; ` A B.

3.0.2 Dynamic Semantics. The dynamic semantics of B is de�ned in Figure 5. Write e 7 ! e 0 for reduction of
expressions. Reduction for operators is standard: each operator application n ~ n 0 is speci�ed by a total meaning
function J~K (n,n 0 ) that preserves types. Reduction for function application is standard. Reduction for type application
is non-standard and discussed below in the reduction of con�gurations.
Conversions are reduced as follows. Conversion from a base type to itself is the identity. Conversion between two
function types, when applied to a value, reduces to a contravariant conversion on the domain (negating the label) and
a covariant conversion on the range. Conversion between two universal types are discussed below. A type name
reduces to itself only if the conversion label refers to a di�erent name. Two mirror image conversions, from A to
and back, reduce to the identity.
Many of the reductions for casts are similar to those for conversion, but some are di�erent. A cast from universal
type to a non-universal type reduces to an instantiation of the polymorphic value at type ?. A cast from ground type
G to ? back to G is the identity whereas a cast from G to ? to a di�erent ground type H raises blame. A cast from a
non-ground type to or from ? factors through it’s unique ground type.
Write . e ! 0 . e 0 for reduction of con�gurations. In addition to handling reduction under an evaluation
context, the reduction of con�gurations also handles the reductions that involve type application, which use the name
store . The application of a type abstraction generates a fresh name and binds it to the instantiating type B in the
store. Then is substituted for the abstraction’s variable X in the body. Finally, a conversion is wrapped around
the body to mediate between it’s type A[ /X ] and the type that the context expects it to have, which is A[B/X ] 2 .
The application of a cast whose target is a universal type 8X .A0 also generates a fresh name and binds it to the
instantiating type B. The is substituted for X in A0 and again, a conversion is inserted to mediate between A0[ /X ]
and A0[B/X ]. Finally, the application of a conversion between 8X .A and 8X .A0 involves generating and binding
it to B, then instantiating at , and substituting for X in the conversion. As in the other cases, a conversion is
inserted to mediate between A0[ /X ] and A0[B/X ].
In general, if ! is a reduction relation, write !⇤ for its re�exive and transitive closure. We write Σ . e + when a
con�guration terminates with a value—that is, as shorthand for 9Σ0, v . Σ . e !⇤ Σ0 . v

2 The reduction rule for type abstraction obtains A, the type of the body, by refering to the type system, but an implementation would not do that.
Instead, we recommend recording the type A during compilation and attaching it to the type abstraction so that it is available in constant time.

9
Type-Name Store Well-Formedness `Σ
<Σ Σ; · ` A
`· ` Σ , :=A

Type Well-Formedness Σ ; ∆ ` A where ` Σ


`Σ X 2∆ `Σ :=A 2 Σ `Σ `Σ ; `A ; `B Σ; ∆ ` A Σ; ∆ ` B Σ; ∆, X ` A
Σ; ∆ ` X Σ; ∆ ` Σ; ∆ ` Σ; ∆ `? ; `A⇥B Σ; ∆ ` A! B Σ ; ∆ ` 8X . A

Convertibility Σ; ∆ ` A B where Σ ; ∆ ` A, Σ ; ∆ ` B , and FTN ( ) 2 Σ

`Σ ; `A A0 ; `B B0 Σ ; ∆ ` A0 A Σ; ∆ ` B B0 Σ; ∆, X ` A B
Σ; ∆ ` ; `A⇥B A ⇥B0 0
Σ; ∆ ` A! B 0
A !B 0
Σ ; ∆ ` 8X . A 8X . B

`Σ :=A 2 Σ `Σ :=A 2 Σ `Σ :=A 2 Σ < `Σ X 2∆ `Σ


Σ; ∆ ` +
A Σ; ∆ ` A Σ; ∆ ` Σ; ∆ ` X X Σ; ∆ `? ?

Label Negation
def
(+ ) =
def
( ) = +

Compatibility Σ; ∆ ` A B where Σ ; ∆ ` A and Σ ; ∆ ` B


`Σ ; ` A A0 ; `B B0 Σ ; ∆ ` A0 A Σ; ∆ ` B B0 Σ; ∆, X ` A B X <A
Σ; ∆ ` ; `A⇥B 0
A ⇥B 0
Σ; ∆ ` A! B 0
A !B 0
Σ; ∆ ` A 8X . B

Σ ; ∆ ` A [?/X ] B `Σ 2Σ `Σ X 2∆ Σ; ∆ ` A Σ; ∆ ` A
Σ ; ∆ ` 8X . A B Σ; ∆ ` Σ; ∆ ` X X Σ; ∆ ` A ? Σ; ∆ `? A

Fig. 3. Type-Level Static Semantics

3.1 Contextual Equivalence


Two open expressions e 1 and e 2 have the same behavior, formally, when they are contextually equivalent (Morris
1968), that is, when substituting one for the other in the context of a larger program does not change the result
of the program. As is common, we de�ne contextual equivalence in terms of contextual approximation. We write
Σ ; ∆ ; Γ ` e 1 ctx e 2 : A to say that e 2 mimics the behavior of e 1 at type A in the context of , , and . Then we write
Σ ; ∆; Γ ` e 1 ⇡ctx e 2 : A to say e 1 and e 2 are contextually equivalent, that is, they approximate each other.

De�nition 3.1. Contextual Approximation and Equivalence

def
Σ ; ∆; Γ ` e 1 ctx e2 : A = Σ; ∆ ; Γ ` e 1 : A ^ Σ ; ∆ ; Γ ` e 2 : A ^
8C , Σ0, B . ` C : (Σ ; ∆ ; Γ ` A ) (Σ0; · ; · ` B ) =)
(Σ . C [e 1 ]+ =) Σ . C [e 2 ]+) ^
0 0

(9 1 . 0 . C[e 1 ] !⇤ 1 . blame p =) 9 2 . 0 . C[e 2 ] !⇤ 2 . blame p )


def
Σ ; ∆; Γ ` e 1 ⇡ctx e2 : A = Σ; ∆ ; Γ ` e 1 ctx e2 : A ^ Σ ; ∆ ; Γ ` e2 ctx e1 : A

10
Environment Well-Formedness Σ ; ∆ ` Γ where ` Σ
`Σ Σ; ∆ ` Γ Σ; ∆ ` A
Σ; ∆ ` · Σ; ∆ ` Γ, x : A

Expression Well-Formedness Σ ; ∆ ; Γ ` e : A where Σ ; ∆ ` Γ and Σ ; ∆ ` A


Σ; ∆ ` Γ Σ; ∆ ` Γ Σ ; ∆ ; Γ ` e : bool Σ ; ∆ ; Γ ` e1 : A Σ ; ∆ ; Γ ` e2 : A Σ; ∆ ` Γ
Σ ; ∆ ; Γ ` true : bool Σ ; ∆ ; Γ ` false : bool Σ ; ∆ ; Γ ` if e then e 1 else e 2 : A Σ ; ∆ ; Γ ` n : int

Σ ; ∆ ; Γ ` e : int Σ ; ∆ ; Γ ` e 0 : int ; ; ` e1 : A ; ; ` e2 : B ; ; `e :A⇥B ; ; `e :A⇥B


Σ ; ∆ ; Γ ` e ~ e : int
0
; ; ` he 1 ,e 2 i : A ⇥ B ; ; ` 1 e :A ; ; ` 2 e :B

Σ; ∆ ` Γ Γ (x ) = A Σ; ∆; Γ, x : A ` e : B Σ; ∆; Γ ` e : B! A Σ ; ∆ ; Γ ` e0 : B
Σ; ∆; Γ ` x : A Σ ; ∆ ; Γ ` (x : A ). e : A ! B Σ ; ∆ ; Γ ` e e0 : A

Σ; ∆, X ; Γ ` v : A Σ; ∆ ` Γ Σ ; ∆ ; Γ ` e : 8X . A Σ; ∆ ` B Σ; ∆; Γ ` e : A Σ; ∆ ` A B
Σ ; ∆ ; Γ ` ⇤X .v : 8X . A Σ ; ∆ ; Γ ` e [B ] : A [B /X ]
Σ ; ∆ ; Γ ` (e : A =) B ) : B

Σ; ∆; Γ ` e : A Σ; ∆ ` A B Σ; ∆ ` Γ Σ; ∆ ` A
p
Σ ; ∆ ; Γ ` (e : A =) B ) : B Σ ; ∆ ; Γ ` blame p : A

Fig. 4. Expression-Level Static Semantics

The well-known problem with contextual equivalence is that it is di�cult to reason about all possible contexts. The
advantage of logical relations is that they provide a means for proving the contextual equivalence of two expressions
that only requires reasoning about the two expressions.

4 LOGICAL RELATION AND PARAMETRICITY


In this section, we present our logical relation for B and prove the Fundamental Property of the logical relation,
which for this language can also be referred to as the Parametricity Theorem. We show that our logical relation is
sound with respect to contextual equivalence—that is, if two programs are logically related then they are contextually
equivalent—which justi�es the use of the logical relation for proving contextual equivalence of programs.

4.1 Main Ideas of the Logical Relation


To establish parametricity for B, we construct a Kripke logical relation which is a logical relation indexed by possible
worlds. Kripke logical relations are needed when reasoning about properties that depend on certain conditions
regarding the state of the computation. The basic idea, then, is to track prevailing conditions in the current world.
Thus, our logical relation for closed terms E JAK relates two expressions e 1 and e 2 in a world W . In contrast, the
logical relation for F (Figure 1) did not require worlds because F is a pure language.
The world W keeps track of three ingredients which we now discuss in turn.
First, a world W contains a natural number j that, intuitively, represents the number of steps left in the computation.
In essence, we need step-indexed logical relations because B contains the dynamic type ? which, semantically,
behaves like the following universal type U encoded using recursive types and tagged sums:

U = µX . + (X ! X ) + ( 1 + ... + n)

where 1 , . . . , n are the set of type names that have been generated thus far. Thus, unlike F, the logical relation
cannot simply be de�ned by primitive recursion on the indexing type.
Second, a world W keeps track of the (current) type-name stores Σ 1 and Σ 2 under which the expressions e 1 and e 2 ,
respectively, should be type checked and evaluated.

11
Reduction of Expressions e 7 ! e0

n ~ n0 7 ! J~K (n,n 0 )
if true then e 1 else e 2 7 ! e1
if false then e 1 else e 2 7 ! e2
( (x : A ). e ) v 7 ! e [v /x ]
1 h 1, 2i 7 ! 1
2 h 1, 2i 7 ! 2

(v : =) ) 7 ! v
(h 1 , 2 i : A ⇥ B =) A0 ⇥ B 0 ) 7 ! h( 1 : A =) B),( 2 : A0 =) B 0 )i
(v : A ! B =) A 0 ! B 0 ) v 0 7 ! (v (v 0 : A 0 =) A ) : B =) B 0 )
(v : =) ) 7 ! v if <
+
((v : A =) ): =) A ) 7 ! v
(v : ? =) ?) 7 ! v
p
(v : =) ) 7 ! v
p p p
(h 1 , 2 i : A ⇥ B =) A0 ⇥ B 0) 7 ! h( 1 : A =) B),( 2 : A0 =) B 0 )i
p p p
(v : A ! B =) A 0 ! B 0 ) v 0 7 ! (v (v 0 : A 0 =) A ) : B =) B 0 )
p p
(v : 8X . A =) B ) 7 ! (v [?] : A [?/X ] =) B ) if B , 8Y . B 0 for any Y , B 0
p
(v : =) ) 7 ! v
p
(v : ? =) ?) 7 ! v
p q
((v : G =) ?) : ? =) G ) 7 ! v
p q
((v : G =) ?) : ? =) H ) 7 ! blame q if G , H
p p p
(v : A =) ?) 7 ! ((v : A =) G) : G =) ?) if A ⇠ G, A , G, A , ?
p p p
(v : ? =) A) 7 ! ((v : ? =) G) : G =) A) if A ⇠ G, A , G, A , ?

Reduction of Con�gurations Σ .e ! Σ0 . e 0

e 7 ! e0 Σ .e ! Σ 0 . e0
Σ . E [e ] ! Σ . E [e 0 ] Σ . E [e ] ! Σ 0 . E [e 0 ] Σ . E [blame p ] ! Σ . blame p

; (·, X ); · ` v : A < dom( )


+
Σ . (⇤X .v ) [B ] ! Σ , :=B . (v [ /X ] : A[ /X ] =) A[B /X ])

< dom( )
p p +
. ( : A =) 8X . A0 ) [B] ! , :=B . (( : A =) A0 [ /X ]) : A0 [ /X ] =) A0 [B/X ])

< dom( )
+
. ( : 8X . A =) 8X . A0 ) [B] ! , :=B . (( [ ] : A[ /X ] =) A0 [ /X ]) : A0 [ /X ] =) A0 [B/X ])

Fig. 5. Dynamic Semantics

Finally, for any related type names in the two programs, W keeps track of the relational interpretation R that
should be used to relate values of type . Intuitively, what makes these type names “related” is that they were
generated (earlier in the computation) when both programs performed some type application that we wish to relate.
The placement of a map from type names to relational interpretations in worlds is a signi�cant departure from the

12
Atomn [A 1 , A 2 ] = {(W , e 1 , e 2 ) | W .j < n ^ W 2 Worldn ^ W .Σ 1 ; · ; · ` e 1 : A 1 ^ W .Σ 2 ; · ; · ` e 2 : A 2 }
Atomval
n [A 1 , A 2 ] = {(W , v 1 , v 2 ) 2 Atomn [A 1 , A 2 ] }
Reln [A 1 , A 2 ] = {R ✓ Atomval n [A 1 , A 2 ] | 8(W , v 1 , v 2 ) 2 R. 8W w W . (W , v 1 , v 2 ) 2 R}
0 0
�n
Worldn = {(j, Σ 1 , Σ 2 , ) 2 Nat ⇥ TNStore ⇥ TNStore ⇥ (TName ! Relj ) |
j < n ^ ` Σ 1 ^ ` Σ 2 ^ 8 2 dom( ). ( ) 2 Relj [Σ 1 ( ), Σ 2 ( )] }
S
Atom [A ] = {(W , e 1 , e 2 ) 2 Atomn [ (A ), (A )] }
nS0
World = Worldn
n 0

bRc n = {(W , e 1 , e 2 ) 2 R | W .j < n}


b cn = { 7! bRc n | ( ) = R}

def
W0 w W = W 0 .j  W .j ^ W 0 .Σ 1 ◆ W .Σ 1 ^ W 0 .Σ 2 ◆ W .Σ 2 ^ W 0 . w bW . cW 0 .j ^ W ,W 0 2 World
def
0 w = 8 2 dom( ). 0 ( ) = ( )
def
W0 wn W = W 0 .j + n = W .j ^ W 0 w W

IR = {(W , e 1 , e 2 ) | W .j > 0 =) (IW , e 1 , e 2 ) 2 R}


def
I(j + 1, Σ 1 , Σ 2 , ) = (j , Σ 1 , Σ 2 , b c j )

def
W ( , B 1 , B 2 , R) = (W .j,W .Σ 1 , :=B 1 ,W .Σ 2 , :=B 2 ,W . [ 7! R])

Fig. 6. Logical Relation: Auxiliary Definitions

logical relation for F (Figure 1), where instead the maps type variables to their relational interpretation. This
change is the result of moving from static enforcement of parametricity to dynamic enforcement with RTG.3
An essential part of Kripke logical relations is a world extension relation W 0 w W that speci�es constraints on
how the current world W may evolve into a future world W 0—intuitively, capturing how the properties of the state
evolve from W to W 0 as the computation progresses. In our logical relation, we allow the step index to decrease
over time as steps are used up by the computation, while allowing type-name stores and the �nite map from type
names to relational interpretations to grow over time as new type names are generated (ensuring that we don’t forget
information about existing type names).

4.2 Logical Relation, Formally Defined


The logical relation for B is de�ned in Figures 6 and 7.
Preliminaries. We start by specifying the semantic objects used in the construction of the logical relation (Figure 6,
top). We �rst explain the basic properties of these semantic objects and then discuss details related to step indexing.
We construct relational interpretations of types as sets of atoms of the form (W , e 1 , e 2 ) where the worlds describe
the set of assumptions under which the pair of expressions are related. Atomn [A1 , A2 ] requires that e 1 and e 2 have
the types A1 and A2 under the type-name stores Σ 1 and Σ 2 from the world W .
Worlds W are 4-tuples of the form (j, Σ 1 , Σ 2 , ). (We use dot notation W .j, W . 1 , W . 2 , W . to project out the
relevant components of world W .) Here j is a natural number repesenting the step index, Σ 1 and Σ 2 are the type-name
stores under which the terms being related are type checked and evaluated, and is a �nite map from type names
to admissible relations R that relate values of type Σ 1 ( ) and Σ 2 ( ).

3 Technically,due to the nondeterministic nature of type-name generation, those two type applications could have generated di�erent type names
1 and 2 , with some type variable X replaced by 1 in one program and with 2 in the other. But since we have an in�nite supply of type
names, we can assume without loss of generality that we can always generate the same fresh name for both programs when using the logical
relation to reason about equivalence. This assumption reduces clutter in our logical relation, as otherwise we would have to keep track of a
bijection between a subset of the existing type names of both programs as Neis et al. (2011) and Ahmed et al. (2011b) do.

13
Reln [A1 , A2 ] speci�es the set of admissible relations as relations R that satisfy monotonicity (or closure) under world
extension: if R relates 1 and 2 in a world W , then R must relate 1 and 2 in any future world of W . Monotonicity
ensures that when we extend the world, associating new type names with types and relations, we do not lose or
modify information associated with old type names.
Since relations contain worlds and worlds contain relations (in the codomain of ), we cannot naïvely construct a
set-theoretic model based on the above intentions. As explained by Ahmed (2004) and Ahmed et al. (2009), who present
step-indexed logical relations for ML-style mutable references, a naïve construction would have an inconsistent
cardinality. To eliminate the inconsistency, we stratify both worlds and relations with a step index. We require that
an n-level world W 2 Worldn contains only step indices j < n and interpretations that map type names to j-level
relations R 2 Relj [A1 , A2 ]; and the latter may only contain j-level atoms which contain j-level worlds W 2 Worldj .
Although our logical relation is binary not unary, our world structure is similar to that of Ahmed (2004) because
dynamically generated type names are analogous to dynamically allocated locations in a model of mutable references:
our worlds keep track of interpretations for type names while Ahmed’s worlds track interpretations for heap locations.

Approximation, World Extension, and Later. The bottom half of Figure 6 presents de�nitions of n-approximation
b·c n , world extension (w) and the “later” operation (I). For a set of atoms R, we de�ne the n-approximation of the set
(written bRc n ) as the subset of its elements whose step indices are strictly smaller than n. For any interpretation
mapping type names to relational interpretations, we de�ne the n-approximation (written b c n ) by applying b·c n to
all of the relations R in the codomain of .
A world W 0 extends W (written W 0 w W ) if W 0 has the same or fewer steps left as W ; if the type-name stores in
W are supersets of the corresponding stores in W ; and if W 0 . remembers the relational interpretations associated
0

with each 2 dom(W . ) up to approximation W 0 .j. Note that this de�nition allows W 0 to provide interpretations
for a superset of the type names that W interprets. Finally, we write W 0 wn W when W 0 extends W and we consume
exactly n steps to get from W to W 0.
Given a world W with a positive step index, we use IW (pronounced “later W ”) to lower the step index of the
world—and of the interpretation in the world—by one. We lift this notion to relational interpretations R as follows:
we say IR relates two expressions in world W if R relates the expressions in IW whenever W has a positive step
index.

Relational Interpretation of Types. Figure 7 presents the de�nition of the logical relation intended to capture
contextual approximation. The value relation V JAK relates closed values—i.e., values with no free type or term
variables, though they may have free type names. The expression relation E JAK relates similarly closed expressions.
The value and expression relations are parametrized by a type substitution that maps free type variables X in A
to type names . Note that, unlike existing logical relations for polymorphic languages—such as the one shown in
Section 2 or the related work by Neis et al. (2011) and Ahmed et al. (2011b)— does not map type variables X to
relational interpretations R. Instead speci�es a mapping from type variables X to type names and we look up the
relational interpretation for (which is the same as the relational interpretation we wish to use for X ) in the world
W . We return to this point below when we discuss the value relation for universal types.
The relation V JAK speci�es when closed values v 1 and v 2 are related in a world W . It requires that v 1 and v 2
have type (A) under the type-name stores W .Σ 1 and W .Σ 2 , respectively. The de�nition of V JAK is straightforward
for base types and pairs. As usual, two values are related at a base type in any world W as long as they are equal.
Two pairs are related at the type A ⇥ B in a world W if the �rst components of the pairs are related at type A in W
and the second components are related at type B in W .
Functions v f 1 and v f 2 are related at A! B in world W if, in any future world W 0 that extends W , given two
arguments v 1 and v 2 related in W 0, the functions applied to the arguments are related expressions at type B in world
W 0. The extension to a future world W 0 is essential for proving monotonicity of V JA! BK under world extension.
Note that in B, the values v f 1 and v f 2 may each be a function abstraction or a conversion or cast from a value to a
function type.
The de�nition of V J8X . AK is non-standard in some respects. First, note that it must relate values v f 1 and v f 2 ,
which may each be a type abstraction or a conversion or cast from a value to a universal type. V J8X . AK says
that v f 1 and v f 2 are related in world W if, in any future world W 0 that extends W , given two types B 1 and B 2 that
are well formed under the type-name stores from W 0, and given a W 0 .j-level admissible relation R 2 Rel [B 1 , B 2 ], the

14
V Jint K = {(W , n , n ) 2 Atom [int ] }
V Jbool K = {(W , b , b ) 2 Atom [bool ] }
V JA ⇥ BK = {(W , h 1 , 2 i, h 10 , 20 i) 2 Atom [A ⇥ B] | (W , 1 , 2 ) 2 V JAK ^ (W , 10 , 20 ) 2 V JBK }
V JA ! B K = {(W , v f 1 , v f 2 ) 2 Atom [A ! B ] |
8W 0 w W . 8v 1 , v 2 . (W 0, v 1 , v 2 ) 2 V JA K =) (W 0, v f 1 v 1 , v f 2 v 2 ) 2 E JB K }
V J8X . A K = {(W , v f 1 , v f 2 ) 2 Atom [8X . A ] |
8W 0 w W . 8B 1 , B 2 , R. 8e 1 , e 2 . 8 .
W 0 .Σ 1 ; · ` B 1 ^ W 0 .Σ 2 ; · ` B 2 ^ R 2 RelW 0 .j [B 1 , B 2 ] ^
+
W 0 .Σ 1 . v f 1 [B 1 ] ! W 0 .Σ 1 , :=B 1 . (e 1 : (A )[ /X ] =) (A )[B 1 /X ]) ^
+
W 0 .Σ 2 . v f 2 [B 2 ] ! W 0 .Σ 2 , :=B 2 . (e 2 : (A )[ /X ] =) (A )[B 2 /X ]) =)
(W 0 ( , B 1 , B 2 , R), e 1 , e 2 ) 2 IE JA K [X !
7 ]}
V JX K = {(W , (v 1 : A 1 =) ), (v 2 : A 2 =) )) 2 Atom [X ] |
(W , v 1 , v 2 ) 2 IW . ( )}
VJ K = {(W , (v 1 : A 1 =) ), (v 2 : A 2 =) )) 2 Atom [ ] ; |
(W , v 1 , v 2 ) 2 IW . ( )}
p p
V J?K = {(W , (v : =) ?), (v : =) ?)) 2 Atom [?] ;}
p p
[ {(W , (v 1 : ?! ? =) ?), (v 2 : ?! ? =) ?)) 2 Atom [?] ; | (W , v 1 , v 2 ) 2 IV J?! ?K }
p p
[ {(W , (v 1 : =) ?), (v 2 : =) ?)) 2 Atom [?] ; |
v1 = (v10 : A 1 =) ) ^ v 2 = (v20 : A 2 =) ) ^ (W , v10 , v20 ) 2 IW . ( )}

E JA K = {(W , e 1 , e 2 ) 2 Atom [A ] | 8j < W .j.


(8 1 , 1 . W . 1 . e 1 !j 1 . 1 =) 9W 0, 2 , 2 . W . 2 . e 2 !⇤ 2 . 2 ^
W 0 wj W ^ W 0 . 1 = 1 ^ W 0 . 2 = 2 ^ (W 0, 1 , 2 ) 2 V JAK ) ^
(8 1 , p. W . 1 . e 1 !j 1 . blame p =) 9 2 . W . 2 . e 2 !⇤ 2 . blame p )}

S J· K = World
S JΣ , :=A K = S JΣ K \ {W 2 World | W .Σ 1 ( ) = A ^ W .Σ 2 ( ) = A ^ `W .Σ 1 ^ `W .Σ 2 ^
⌅ ⇧
W . ( ) = V JA K ; W .j }

D J· K = {(W , ;) | W 2 World}
D J∆ , X K = {(W , [X 7! ]) | (W , ) 2 D J∆ K ^ 2 dom(W . )}

G J· K = {(W , ;) | W 2 World}
G JΓ , x : A K = {(W , [x 7! (v 1 , v 2 )]) | (W , ) 2 G JΓ K ^ (W , v 1 , v 2 ) 2 V JA K }

def
Σ ; ∆ ; Γ ` e1 e2 : A = Σ ; ∆ ; Γ ` e1 : A ^ Σ ; ∆ ; Γ ` e2 : A ^
8W , , . (W 2 S JΣ K ^ (W , ) 2 D J∆ K ^ (W , ) 2 G JΓ K ) =)
(W , ( 1 (e 1 )), ( 2 (e 2 ))) 2 E JA K

def
Σ ; ∆ ; Γ ` e1 ⇡ e2 : A = Σ ; ∆ ; Γ ` e1 e 2 : A ^ Σ ; ∆ ; Γ ` e2 e1 : A

Fig. 7. Logical Relation

type applications v f 1 [B 1 ] and v f 2 [B 2 ] must be related. The non-standard aspect of the de�nition is how we specify
relatedness of the aforementioned type applications.
Unlike Ahmed et al. (2011b) and Neis et al. (2011), who require that the type applications v f 1 [B 1 ] and v f 2 [B 2 ] are
related in E JAK with an environment that maps X to (B 1 , B 2 , R), in a world that extends W 0 to record (essentially)
that X maps to the type name and the triple (B 1 , B 2 , R), we avoid duplicating the information (B 1 , B 2 , R) in both
and the world. Instead we rely on the indirection provided by type names. That is, we let specify simply that X
maps to type name and store the types and relational interpretation for in the world (written W 0 ( , B 1 , B 2 , R)
which is de�ned at the bottom of Figure 6).

15
But having made the above design decision, we have a bit of problem regarding how to specify relatedness of the
type applications v f 1 [B 1 ] and v f 2 [B 2 ] in the de�nition of V J8X . A K . We proceed by noting that the operational
semantics guarantees that regardless of whether the values f i are type abstractions or conversions or casts to
+
universal type, a type application . f i [Bi ] steps to a con�guration of the form , :=Bi . (ei : (A )[ /X ] =)
(A )[Bi /X ]). Thus, V J8X . AK requires that the subexpressions e 1 and e 2 be related in IE JAK [X 7! ] in world
W 0 ( , B 1 , B 2 , R). (At the end of Section 4.2, we explain why the dynamic semantics of type application in B
precludes a more standard logical-relation design where maps type variables X to triples (B 1 , B 2 , R).)
We use IE JAK because we must ensure that we go down a step to avoid circularities due to impredicative
polymorphism (as pointed out by Ahmed (2004)). Speci�cally, consider what happens if B 1 and B 2 happen to be the
type (8X . A )—i.e., types that are not strictly smaller than the type whose relational interpretation we wish to de�ne.
Then, to ensure that our de�nition of V J8X . AK at world W is well founded, when we relate e 1 and e 2 we must
use only the (W .j 1)-approximation of R (where W .j W 0 .j). Intuitively, this is justi�ed since type application
consumes a reduction step.
The relation V JX K relates values of type (X ) = . Hence, the values must be of the form ( i : Ai =) ) for
i 2 {1, 2}. These values are related if the underlying 1 and 2 are related by the relational interpretation for (i.e.,
W . ( )) for one fewer step.
The relation V J K also relates values of type . Hence, the values must again be of the form ( i : Ai =) ) for
i 2 {1, 2}. As above, these values are related if the underlying 1 and 2 are related by W . ( ) for one fewer step.
p p
The relation V J?K relates values of the form (v 1 : G =) ?) and (v 2 : G =) ?) in world W , where both values
have the same ground type G. There are three cases to consider. When G is a base type, 1 and 2 must be equal.
When G is ?! ?, 1 and 2 must be related at the type ?! ? in world W for one fewer step. Since our de�nition of
the value relation at ? relies on the value relation for the bigger type ?! ?, it is imperative that we go down a step to
ensure that the logical relation is well founded. Going down a step is justi�ed since extracting the values i from
p
( i : ?! ? =) ?) consumes a reduction step. Finally, when G is a type name , the values 1 and 2 must be of the
form ( i : Ai
0 =) ) and and are related by the relational interpretation for (i.e., W . ( )) for one fewer step.
0
1
0
2
The expression relation E JAK is similar to prior step-indexed Kripke logical relations (in particular, Matthews
and Ahmed (2008)). It says that two expressions e 1 and e 2 are related in world W if whenever e 1 evaluates to a value
under W .Σ 1 in fewer than W .j steps, then e 2 evaluates to a value under W .Σ 2 and the resulting values and stores are
related in some future world W 0; and whenever e 1 evaluates to blame p under W .Σ 1 then e 2 evaluates to blame p
under W .Σ 2 .
The remaining de�nitions in Figure 7 specify the logical relation for open terms. First, S JΣ K speci�es worlds W
that satisfy Σ. It says that the type-name stores in W should be well formed, and for every := A 2 , the type-name
stores in W should map to A and the interpretation W . should map to the W .j-approximation of V JAK ;. Next,
D J K says that a type substitutions satis�es in a world W if it maps all the type variables in to type names
that are associated with a relational interpretation in W . . Finally, we let the metavariable range over relational
value substitutions, i.e., �nite maps from variables to pairs of values. G J K says that satis�es in world W if
every variable in x 2 dom( ) is mapped to pairs of values related in V J (x )K in W .
The logical approximation relation on open terms Σ; ∆; Γ ` e 1 e 2 : A says that given a world W that satis�es Σ ,
a type substitution that maps type variables in ∆ to type names in W , and a relational value substitution that
maps variables to pairs of values related in W , the terms ( 1 (e 1 )) and ( 2 (e 2 )) are related in E JAK at world W .
The logical equivalence relation Σ; ∆ ; Γ ` e 1 ⇡ e 2 : A requires that e 1 logically approximates e 2 and vice versa.

Why the Interpretation of Universal Types is Non-standard. Consider de�ning the logical relation in the standard
way with value interpretations parametrized by an environment that maps type variables X to triples (B 1 , B 2 , R)
that record the types B 1 and B 2 that X was instantiated with and the relational interpretation R that should be used to

16
relate values at the type X . Then our interpretation of type variables and universal types may be as follows:
V JX K = R where (X ) = (B 1 , B 2 , R)
V J8X . AK = {(W , v f 1 , v f 2 ) 2 Atom [8X . A ] |
8W 0 w W . 8 , B 1 , B 2 , R.
W 0 .Σ 1 ; · ` B 1 ^ W 0 .Σ 2 ; · ` B 2 ^ R 2 RelW 0 .j [B 1 , B 2 ] =)
(W 0 ( , B 1 , B 2 , R), v f 1 [B 1 ], v f 2 [B 2 ]) 2 E JAK [X 7! (B 1 , B 2 , R)]}
With the above de�nitions, assuming a standard de�nition of the open term relation, we fail to prove the compatibility
lemma for type abstraction. That lemma says: if Σ; ∆, X ; Γ ` v 1 v 2 : A then Σ; ∆; Γ ` ⇤X .v 1 ⇤X .v 2 : 8X . A . Next,
we show the proof attempt for a simpler version of that lemma which says: if ·; ·, X ; · ` v 1 v 2 : A then ·; · ; ·
` ⇤X .v 1 ⇤X .v 2 : 8X . A.
Given W that satis�es the empty type-name store, it su�ces to show that (W , ⇤X .v 1 , ⇤X .v 2 ) 2 V J8X . AK ;.
Unrolling the de�nition given above, we assume appropriate W 0, , B 1 , B 2 , and R and need to show
(W 0 ( , B 1 , B 2 , R), (⇤X .v 1 ) [B 1 ], (⇤X .v 2 ) [B 2 ]) 2 E JA K ;[X 7! (B 1 , B 2 , R)]
or equivalently (after taking a step),
+
*W 0 (v 1 [ /X ] : A[ /X ] =) A[B 1 /X ]), +
( , B 1 , B 2 , R), + 2 IE JA K [X 7! (B 1 , B 2 , R)]
, (v 2 [ /X ] : A[ /X ] =) A[B 2 /X ]) -
But instantiating the premise ·; ·, X ; · ` v 1 v 2 : A with W 0 ( , B 1 , B 2 , R) and ;[X 7! (B 1 , B 2 , R)] gives us:
(W 0
( , B 1 , B 2 , R), v 1 [B 1 /X ], v 2 [B 2 /X ]) 2 E JAK [X 7! (B 1 , B 2 , R)]
and we now have no way of completing the proof.
The problem here is that the logical relation for open terms merely substitutes the Bi for X while the reduction rule
for type application substitutes a fresh type name for X and then performs a conversion from A[ /X ] to A[Bi /X ].
To �x this mismatch, we would at a minimum need to make a mapping from type variables X to ( , B 1 , B 2 , R) so
we can keep track of the type name generated for each X . In addition to that, the logical relation for open terms
Σ ; ∆; Γ ` e 1 e 2 : A would have to be modi�ed so that once we have picked a world W that satis�es ; a that maps
all X 1 , . . . , X n in to ( 1 , B 11 , B 12 , R 1 ), . . . , ( n , Bn1 , Bn2 , Rn ), where the i are fresh type names with respect to the
type-name stores in W ; and a substitution that satis�es , we would require that the two terms being related by
E JAK (for j 2 {1, 2}) be of the form:
+ 1
((e j [ 1 /X 1 ] . . . [n /X n ] : A[ 1 /X 1 ] . . . [ n /X n ] =) A[B 1j /X 1 ][ 2 /X 2 ] . . . [ n /X n ]) ...
+ n
: A[B 1j /X 1 ] . . . [B (n 1)j /X n 1 ][ n /X n ] =) A[B 1j /X 1 ] . . . [Bnj /X n ])
Clearly, the logical relation design we just sketched out is much more complicated than the logical relation we
present in this paper. The lesson here is that every logical relation must “listen” to the (static and dynamic semantics
of) the language at hand. The design of B presents di�erent challenges in the design of the logical relation compared
to the related work by Neis et al. (2011) and Ahmed et al. (2011b) even though all three use Kripke logical relations
(which is to be expected for any language with RTG). We give a detailed comparison with the aforementioned related
work in Section 6.

4.3 Parametricity and Soundness of the Logical Relation


In this section, we summarize the proofs for the Fundamental Property and soundness of the logical relation with
respect to contextual equivalence. The full proofs are in the supplementary material.
The Fundamental Property is that any well-typed term of B is related to itself by the logical relation.
T������ 4.1 (F���������� P������� / P������������). If Σ ; ∆ ; Γ ` e : A, then Σ ; ∆ ; Γ ` e e : A.
The proof of the fundamental property is by induction on the derivation of Σ ; ∆ ; Γ ` e : A , relying on a compatibility
lemma for each kind of expression in B. The compatibility lemmas for conversion, type application, and cast are
interesting.

17
For conversion, the proof boils down to showing that if some expressions e 1 and e 2 are related, applying a conversion
to them, either positively or negatively, yields related expressions:
+ +
Σ; ∆ ` A + B and (W , e 1 , e 2 ) 2 E JAK implies (W , (e 1 : (A ) =) (B )), (e 2 : (A ) =) (B ))) 2 E JB K
Σ; ∆ ` B A and (W , e 1 , e 2 ) 2 E JB K implies (W , (e 1 : (B ) =) (A )), (e 2 : (B ) =) (A ))) 2 E JAK
We prove these two statements simultaneously by induction on the size of A, using numerous technical lemmas about
the logical relation (e.g., anti-reduction, monotonicity, and compositionality).
The proof of compatibility for type application requires that we show
(W , 1, 2 ) 2 V J8X . AK implies (W , 1 [ (B)], 1 [ (B)]) 2 E JA[B/X ]K
The proof of this does not require induction, but it uses the above property of conversion as well as many of the same
technical lemmas.
The proof of compatibility for casts boils down to showing that if some expressions e 1 and e 2 are related, casting
them yields related expressions:
p p
Σ; ∆ ` A B and (W , e 1 , e 2 ) 2 E JAK implies (W , e 1 : (A) =) (B), e 2 : (A) =) (B)) 2 E JBK
We prove this by induction on the step index in W and on the derivation of Σ ; ∆ ` A B . The induction on the step
index is necessary to handle the cases for casting to and from ?. We rely on the above property of type application
for the cast from 8X .A0 to ?.
Next we discuss the proof that the logical relation is sound with respect to contextual approximation (and therefore
contextual equivalence).
T������ 4.2 (S�������� �.�.�. C��������� A������������). If Σ; ∆; Γ ` e 1 e 2 : A then Σ ; ∆; Γ ` e 1 ctx e2 : A .
The proof follows the usual route of going through congruence and adequacy.
L���� 4.3 (C���������). If Σ; ∆ ; Γ ` e 1 ⇡ e 2 : A and ` C : (Σ ; ∆ ; Γ ` A ) (Σ0; ∆0; Γ0 ` B )
then Σ0; ∆0; Γ0 ` C [e 1 ] ⇡ C [e 2 ] : B .
Congruence is proved by induction on the type derivation for C, using a weakening lemma for the cases where C is
empty, and the compatibility lemmas for all other cases.
L���� 4.4 (A������). If Σ; · ; · ` e 1 ⇡ e 2 : A then Σ . e 1 + if and only if Σ . e 2 +.
Adequacy follows easily from the de�nition of the logical relation.

5 FREE THEOREM EXAMPLES


We consider two examples of obtaining theorems for free from our parametricity result. The �rst example, about the
K combinator, comes from Ahmed et al. (2011a). The second example comes from Wadler (1989), and revisits our
discussion of swap from Section 2.
We write ` e : A as shorthand for ; · ; · ` e : A. We write e# for the value resulting from normalizing the expression
e, when one exists.

5.1 K Combinator
Ahmed et al. (2011a) discuss the K combinator to motivate the design of the polymorphic lambda calculus, so it is
illustrative to return to this example. On the left we have the untyped K combinator and on the right we the untyped
K combinator again, but with a typo!
K ? = d (x ). ( ). xe badK ? = d (x ). ( ). e
`1 `2
K = (K ? : ? =) 8X .8Y .X ! Y ! X ) badK = (badK ? : ? =) 8X .8Y .X ! Y ! X )
Let us consider the behavior of these two combinators once they are cast to the polymorphic type that one would
expect for the K combinator, that is, 8X .8Y .X ! Y ! X . As explained by Ahmed et al. (2011a), parametricity should
tell us that something of type 8X .8Y .X ! Y ! X is either the constant function or the unde�ned function. Indeed,
the above expression K is an example of the former and badK is an example of the later. Furthermore, with our
parametricity result in hand we can prove that in general, values of type 8X .8Y .X ! Y ! X behave as expected.

18
T������ 5.1 (F��� T������: K�C���������). If ` : 8X . 8Y . X ! Y ! X , ` 1 : A, and ` 2 : B, then either
(1) . [A] [B] 1 2 !⇤ 0 . 10 and 10 ⇡ctx 1 , for some 0, 10 , or
(2) . [A] [B] 1 2 *, or
(3) . [A] [B] 1 2 !⇤ 0 . blame p , for some 0, p.
Proof (sketch)
(The full proof is given in the supplementary material. Here we give the high points.) We focus on case (1)
where [A] [B] reduces to a value. Let e = [A] [B] 1 2 . We need to show that its result 10 is contextually
equivalent to 1 .
By the Fundamental Property (Theorem 4.1), we have
(W0 , , ) 2 V J8X .8Y .X ! Y ! X K ; (14)
The type applications reduce as follows.
+ +
. [A] [B] !⇤ 0
. e1 : ! ! =) A ! ! A =) A ! B ! A (15)
where 0 = , :=A, :=B. Let e0 be the right-hand side of the above reduction. Let 00
1 be the result of
normalizing 1 : A =) A, so we have 00
1 ⇡ctx 1. From (14) and (15) we have
(W1 , e 1 , e 1 ) 2 E J ! ! K; (16)
with W1 . 1( ) = W1 . 2( ) = A, W1 . 1( ) = W1 . 2( ) = B, W1 . ( ) = R X , and W1 . ( ) = RY , where we
choose
val val
R X = {(W , 00 00
1, 1 ) 2 AtomW 0 .j
[A, A]} and RY = {(W , 2, 2 ) 2 AtomW 0 .j
[B, B]} (17)
Next, we have the reduction
0
. e0 1 2 !⇤ 0
. e1 ( 00
1 : A =) ) ( 2 : B =) )
From (17) we have

(W2 , 00
1 : A =) , 00
1 : A =) ) 2 V J K ; and (W2 , 2 : B =) , 2 : B =) ) 2 V J K ;

So from (16) we have that e 1 ( 100 : A =) ) ( 2 : B =) ) reduces to a value r : A =) and


(W3 , r , r ) 2 W3 . ( ) for some W3 w W1 . So (W3 , r , r ) 2 R X and therefore r = 100. Finally, we have the
reduction
+ + +
( 00
1 : A =) =) A =) A) ! ( 00
1 : A =) A) !⇤ 0
1 and 0 ctx
1⇡
00 ctx
1 ⇡ 1.

5.2 Rearrangements Commute with Map


Wadler (1989)’s introductory example of a free theorem showed that any function r of type 8X .List X ! List X (r is
for “rearrangement”) commutes with the map function. That is, for any function f : A ! B and list l : List A,
map f (r [A] l ) = r [B] (map f l ).
Here we derive the analogous free theorem for rearrangements on pairs instead of lists. That is, any function r of
type 8X .X ⇥ X ! X ⇥ X commutes with the pair-mapping operation: map f h 1 , 2 i = hf 1 , f 2 i. Note that in our
setting, functions of type 8X .X ⇥ X ! X ⇥ X include untyped functions that have been cast to this type, such as
`
swap? = d (p). h 2 p, 1 pie : ? =) 8X .X ⇥ X ! X ⇥ X
`
id ? = d (x ). xe : ? =) 8X .X ⇥ X ! X ⇥ X
`
bad ? = d (p). h 1p + 2 p, 42ie : ? =) 8X .X ⇥ X ! X ⇥ X
T������ 5.2 (F��� T������: R������������). Suppose ` r : 8X . X ⇥ X ! X ⇥ X , ` f : A! B, ` : A ⇥ A,
. f ( 1 )+, and . f ( 2 )+. Then ; · ; · ` map f (r [A] ) ⇡ctx r [B] (map f ) : B ⇥ B.

19
Proof (sketch)
(The full proof is given in the supplementary material.) We focus this sketch on the case where r terminates
with a value. The type applications reduce as follows
+
r [A] ! r 0 : ⇥ ! ⇥ =) A ⇥ A ! A ⇥ A
+
r [B] ! r 0 : ⇥ ! ⇥ =) B ⇥ B ! B ⇥ B
By the Fundamental Property (Theorem 4.1), (W0 , r , r ) 2 V J8X .X ⇥ X ! X ⇥ X K ; and therefore
(W1 , r 0, r 0 ) 2 E J ⇥ ! ⇥ K; (18)
in a world W1 with W1 . 1( ) = A, W1 . 2( ) = B, and W1 . ( ) = R X where we choose
val
#) 2 AtomW 0 .j [A, B] | : A} (19)
0 0 0
R X = {(W , ,f `
Let = h 1, 2 i. We have
(W1 , 1 : A =) , f 1# : B =) ) 2 V J K ; and (W1 , 2 : A =) , f 2# : B =) ) 2 V J K ;

Let p = h 1 : A =) , 2 : A =) i and p 0 = hf 1# : B =) , f 2# : B =) i.
So (W1 , p, p 0 ) 2 V J ⇥ K ;. Therefore from (18) we have
(W2 , r 0 p, r 0 p 0 ) 2 E J ⇥ K ;
We have the reductions
r 0 p !⇤ h 3 : A =) , 4 : A =) i
0 0
r p ! h ⇤ 0
3 : B =) , 0
4 : B =) i
so (W3 , 3 , 2 V J K ; and (W3 ,
0
3) 4,
0
4) 2 V J K ;. Therefore, from (19) we have 0
3 =f 3# and 0
4 =f 4 #.
Next we have the reductions
+
h 3 : A =) , 4 : A =) i : ⇥ =) A ⇥ A !⇤ h 3 , 4i
+
hf 3# : B =) , f 4# : B =) i : ⇥ =) B ⇥ B !⇤ hf 3 #, f 4 #i

To put this all together, we have


map f (r [A] ) !⇤ map f h 3 , 4i !⇤ hf 3 #, f 4 #i
r [B] (map f ) ! hf ⇤
3 #, f 4 #i

We conclude that
map f (r [A] h 1 , 2 i)⇡
ctx
r [B] hf 1, f 2i

6 RELATED WORK
The syntactic type abstraction of Grossman et al. (2000) inspired the conversion construct used in this paper. They
use brackets to hide a host’s knowledge that X =A from a client; so their [M]hB corresponds to our negative conversion
+
M : B[ :=A] =) B and their [M]cB corresponds to our positive conversion M : B =) B[ :=A]. In their semantics,
brackets push through , in contrast to our present approach. Grossman et al. (2000) do not prove parametricity but
they do prove a weaker value abstraction property.
Greenberg (2013) and Sekiyama et al. (2017) study a language that combines polymorphism and manifest contracts
(aka. re�nement types), but not type dynamic, and they prove parametricity. In their language parametricity is
enforced statically (as in System F), so no dynamic enforcement is needed.
Non-parametric Polymorphism. Several language designs provide polymorphism but do not enforce parametricity.
The argument in favor of this design choice is that it increases expressiveness. The languages include CAML (Leroy
and Mauny 1991), Typed Racket (Tobin-Hochstadt and Felleisen 2006, 2008, 2010), and those generated by the
Gradualizer (Cimini and Siek 2016, 2017).

20
Sealing for Parametricity. The use of sealing to enforce type abstraction goes back to Morris (1973), who described
a language with a Createseal primitive that returns a pair of functions for sealing and unsealing, which correspond to
encryption and decryption, respectively. The distinction between sealing and runtime type generation is that the seals
are values, not types. Thus, sealing is applicable in untyped languages. Sumii and Pierce (2003) create a simply-typed
-calculus with cryptographic sealing. They de�ne a logical relation and prove parametricity for the language, and
they present an embedding of polymorphic lambda calculus into their calculus (Pierce and Sumii 2000). Their logical
relation uses possible worlds that are analogous to ours, but they connect relational interpretations to private keys
instead of type names. Guha et al. (2007) use sealing in the design of polymorphic contracts for PLT Scheme. Pitts
and Stark (1993) and Stark (1995) study a language with fresh name generation (akin to Scheme’s gensym) and de�ne
a logical relation for reasoning about representation independence. It is straightforward to implement sealing using
name generation and equality on names.

Runtime Type Generation. As discussed in Section 1, Matthews and Ahmed (2008) studied the integration of Scheme
and ML by designing a multi-language that uses RTG to protect ML’s polymorphic functions from Scheme’s runtime
type tests. Their multi-language contains boundaries that mediate between Scheme and ML code and are annotated
with conversion schemes (which are essentially types). Boundaries have the form SM (ML inside, Scheme outside:
convert from to ?) and MS (Scheme inside, ML outside: convert from ? to ). Ahmed et al. (2011b) later �xed their
proof of parametricity, making cosmetic changes to the multi-language in the process. Their reduction rule for type
application is as follows:

K . (⇤X .e) [B] ! K, k . e[X := hk; Bi]

where K is a type-name store, k is a freshly generated type name, and e[X := hk; Bi] denotes a sealing substitution,
which replaces occurences of X in the conversion schemes that appear on boundaries inside e. Performing sealing
substitution on conversion schemes provides two things: (1) a way to locally store type-name bindings, whereas in
B, type-name bindings are kept in a global store; and (2) a means to insert many “local” conversions, whereas in
B, the type application rule performs one “global” conversion from A[ /X ] to A[B/X ]. Recall that at the end of
Section 4.2, we discussed the rami�cations of this global conversion on the design of the logical relation for B. Due
to the sealing substitutions and many-local-conversions aspects of the multi-language design, Ahmed et al. (2011b)
are able to parametrize V JAK with a that maps X to (B 1 , B 2 , R) without the need to store type names in . A �nal
distinction between the Scheme+ML multi-language and B is that the former only allows casts to and from ?, while
we support casts between many more (compatible) types, which makes our calculus more general.
In Section 1, we also discussed the work by Neis et al. (2009) who present a Kripke logical relation for G, a
polymorphic language extended with Girard’s non-parametric J operator, but without the type ?. Since their language
is non-parametric, they have a conversion typing rule that essentially says that if e : A and A ⇡ A0 under some
type-name store (where A ⇡ A0 allows all type names in A and A0 to be replaced by the types they are bound to
in ), then e : A0. In B, we do not have such a conversion rule, which would break parametricity. These language
distinctions lead to di�erences in the design of the logical relation as discussed in Section 4.2.

7 CONCLUSION
This paper settles a long-standing open question: can a language that integrates dynamic typing into a statically
typed language with universal types satisfy parametricity? In the setting of the polymorphic blame calculus of Ahmed
et al. (2011a), we de�ne a Kripke logical relation, prove the Fundamental Property (Theorem 4.1), and prove that the
logical relation is sound with respect to contextual equivalence (Theorem 4.2). To demonstrate the utility of this
parametricity result, we prove two free theorems, one about the K combinator and the other a classic example about
rearrangements.
Looking to the future, we see several lines of research. Igarashi (2017) recently pointed out a challenge regarding
how polymorphism should interact with the gradual guarantee of Siek et al. (2015). It would also be interesting to
investigate how our work carries over to a setting with implicit polymorphism in the style of ML. Second, we plan to
develop a coercion-based version of the polymorphic blame calculus with the goal of acheiving space e�ciency.

21
ACKNOWLEDGMENTS
This material is based upon work supported by the National Science Foundation under Grant No. nnnnnnn and Grant
No. mmmmmmm. Any opinions, �ndings, and conclusions or recommendations expressed in this material are those
of the author and do not necessarily re�ect the views of the National Science Foundation.

REFERENCES
Martín Abadi, Luca Cardelli, Benjamin Pierce, and Gordon Plotkin. 1991. Dynamic Typing in a Statically Typed Language. ACM Transactions on
Programming Languages and Systems 13, 2 (April 1991), 237–268.
M. Abadi, L. Cardelli, B. Pierce, and D. Rémy. 1995. Dynamic typing in polymorphic languages. Journal of Functional Programming 5 (1995),
111–130.
Amal Ahmed, Derek Dreyer, and Andreas Rossberg. 2009. State-Dependent Representation Independence. In ACM Symposium on Principles of
Programming Languages (POPL), Savannah, Georgia.
Amal Ahmed, Robert Bruce Findler, Jeremy Siek, and Philip Wadler. 2011a. Blame for All. In ACM Symposium on Principles of Programming
Languages (POPL), Austin, Texas. 201–214.
Amal Ahmed, Lindsey Kuper, and Jacob Matthews. 2011b. Parametric polymorphism through run-time sealing, or, Theorems for low, low prices!
(April 2011). Available at http://www.ccs.neu.edu/home/amal/papers/paramseal-tr.pdf.
Amal Ahmed, Jacob Matthews, Robert Bruce Findler, and Philip Wadler. 2009. Blame for all. In Workshop on Script-to-Program Evolution (STOP).
1–13.
Amal Ahmed, James T. Perconti, Jeremy G. Siek, and Philip Wadler. 2014. Blame for All (revised). (August 2014). draft.
Amal Jamil Ahmed. 2004. Semantics of Types for Mutable State. Ph.D. Dissertation. Princeton University.
Esteban Allende, Oscar Callaú, Johan Fabry, Éric Tanter, and Marcus Denker. 2013. Gradual Typing for Smalltalk. Science of Computer Programming
(Aug. 2013). Available online.
Gavin Bierman, Martín Abadi, and Mads Torgersen. 2014. Understanding TypeScript. In ECOOP 2014 – Object-Oriented Programming, Richard
Jones (Ed.). Lecture Notes in Computer Science, Vol. 8586. Springer Berlin Heidelberg, 257–281.
Gilad Bracha. 2011. Optional Types in Dart. Google.
Avik Chaudhuri. 2014. Flow: a static type checker for JavaScript. (2014). http://�owtype.org/
Matteo Cimini and Jeremy G. Siek. 2016. The Gradualizer: a methodology and algorithm for generating gradual type systems. In Symposium on
Principles of Programming Languages (POPL).
Matteo Cimini and Jeremy G. Siek. 2017. Automatically Generating the Dynamic Semantics of Gradually Typed Languages. In Symposium on
Principles of Programming Languages (POPL).
Robert Bruce Findler and Matthias Felleisen. 2002. Contracts for higher-order functions. In International Conference on Functional Programming
(ICFP), Pittsburgh, Pennsylvania. 48–59.
Jean-Yves Girard. 1972. Interprétation Fonctionnelle et Élimination des Coupures de l’Arithmétique d’Ordre Supérieur. Thèse de doctorat d’état.
Université Paris VII, Paris, France.
Michael Greenberg. 2013. Manifest Contracts. Ph.D. Dissertation. University of Pennsylvania.
Michael Greenberg, Benjamin C. Pierce, and Stephanie Weirich. 2010. Contracts made manifest. In ACM Symposium on Principles of Programming
Languages (POPL), Madrid, Spain. 353–364.
Jessica Gronski, Kenneth Knowles, Aaron Tomb, Stephen N. Freund, and Cormac Flanagan. 2006. Sage: Hybrid Checking for Flexible Speci�cations.
In Scheme and Functional Programming Workshop (Scheme). 93–104.
Dan Grossman, Greg Morrisett, and Steve Zdancewic. 2000. Syntactic Type Abstraction. ACM Transactions on Programming Languages and Systems
22, 6 (Nov. 2000), 1037–1080.
Arjun Guha, Jacob Matthews, Robert Bruce Findler, and Shriram Krishnamurthi. 2007. Relationally-Parametric Polymorphic Contracts. In Dynamic
Languages Symposium (DLS). 29–40.
Robert Harper. 2013. Practical Foundations for Programming Languages. Cambridge University Press.
Anders Hejlsberg. 2010. C# 4.0 and beyond by Anders Hejlsberg. Microsoft Channel 9 Blog. (April 2010).
Anders Hejlsberg. 2012. Introducing TypeScript. Microsoft Channel 9 Blog. (2012).
Fritz Henglein. 1994. Dynamic typing: syntax and proof theory. Science of Computer Programming 22, 3 (June 1994), 197–230.
Yuu Igarashi. 2017. A gradually typed polymorphic lambda calculus. In Symposium on Principles of Programming Languages (POPL). (poster).
Lintaro Ina and Atsushi Igarashi. 2011. Gradual typing for generics. In Proceedings of the 2011 ACM international conference on Object oriented
programming systems languages and applications (OOPSLA ’11).
Xavier Leroy and Michel Mauny. 1991. Dynamics in ML. Springer Berlin Heidelberg, Berlin, Heidelberg, 406–426. DOI:http://dx.doi.org/10.1007/
3540543961_20
Jacob Matthews and Amal Ahmed. 2008. Parametric polymorphism through run-time sealing, or, Theorems for low, low prices!. In European
Symposium on Programming (ESOP). 16–31.
Jacob Matthews and Robert Bruce Findler. 2007. Operational Semantics for Multi-Language Programs. In ACM Symposium on Principles of
Programming Languages (POPL), Nice, France. 3–10.
James H. Morris. 1968. Lambda-calculus Models of Programming Languages. Ph.D. Dissertation. MIT, Cambridge, MA, USA.
James H. Morris, Jr. 1973. Protection in Programming Languages. Commun. ACM 16, 1 (Jan. 1973), 15–21.
Georg Neis, Derek Dreyer, and Andreas Rossberg. 2009. Non-Parametric Parametricity. In International Conference on Functional Programming
(ICFP), Edinburgh, Scotland. 135–148.
Georg Neis, Derek Dreyer, and Andreas Rossberg. 2011. Non-parametric parametricity. Journal of Functional Programming 21 (2011), 497–562.

22
Xinming Ou, Gang Tan, Yitzhak Mandelbaum, and David Walker. 2004. Dynamic Typing with Dependent Types. In IFIP International Conference on
Theoretical Computer Science. 437–450.
Benjamin Pierce and Eijiro Sumii. 2000. Relating cryptography and polymorphism. (2000). www.cis.upenn.edu/~bcpierce/papers/infohide.ps
Manuscript.
Andrew M. Pitts. 1998a. Existential Types: Logical Relations and Operational Equivalence. Lecture Notes in Computer Science 1443 (1998), 309–326.
Andrew M. Pitts. 1998b. Existential types: Logical relations and operational equivalence. Springer Berlin Heidelberg, Berlin, Heidelberg, 309–326.
DOI:http://dx.doi.org/10.1007/BFb0055063
Andrew M. Pitts and Ian D. B. Stark. 1993. Observable Properties of Higher Order Functions That Dynamically Create Local Names, or What’s
New?. In Proceedings of the 18th International Symposium on Mathematical Foundations of Computer Science (MFCS ’93). Springer-Verlag, London,
UK, UK, 122–141.
John C. Reynolds. 1974. Towards a Theory of Type Structure. In Programming Symposium (LNCS), Vol. 19. Springer-Verlag, 408–425.
John C. Reynolds. 1983. Types, abstraction, and parametric polymorphism. Information Processing (1983), 513–523.
Andreas Rossberg. 2003. Generativity and dynamic opacity for abstract types. In ACM Conference on Principles and Practice of Declarative
Programming (PPDP). 241–252.
Andreas Rossberg. 2006. The Missing Link: Dynamic Components for ML. In Proceedings of the Eleventh ACM SIGPLAN International Conference on
Functional Programming (ICFP ’06). ACM, New York, NY, USA, 99–110. DOI:http://dx.doi.org/10.1145/1159803.1159816
Taro Sekiyama, Atsushi Igarashi, and Michael Greenberg. 2017. Polymorphic Manifest Contracts, Revised and Resolved. ACM Trans. Program.
Lang. Syst. 39, 1, Article 3 (Feb. 2017), 36 pages. DOI:http://dx.doi.org/10.1145/2994594
Peter Sewell. 2001. Modules, Abstract Types, and Distributed Versioning. In Proceedings of the 28th ACM SIGPLAN-SIGACT Symposium on Principles
of Programming Languages (POPL ’01). ACM, New York, NY, USA, 236–247.
Jeremy G. Siek and Walid Taha. 2006. Gradual Typing for Functional Languages. In Scheme and Functional Programming Workshop (Scheme). 81–92.
Jeremy G. Siek, Michael M. Vitousek, Matteo Cimini, and John Tang Boyland. 2015. Re�ned Criteria for Gradual Typing. In SNAPL: Summit on
Advances in Programming Languages (LIPIcs: Leibniz International Proceedings in Informatics).
Jeremy G. Siek and Philip Wadler. 2010. Threesomes, with and without blame. In ACM Symposium on Principles of Programming Languages (POPL).
365–376.
Jeremy G. Siek and Philip Wadler. 2017. Conversions and casts: compare and contrast. (January 2017). submitted for publication.
Ian Stark. 1995. Names and Higher-Order Functions. Ph.D. Dissertation. University of Cambridge.
Richard Statman. 1991. A local translation of untyped [lambda] calculus into simply typed [lambda] calculus. Technical Report. Carnegie-Mellon
University.
Eijiro Sumii and Benjamin Pierce. 2003. Logical relations for encryption. J. Comput. Secur. 11, 4 (July 2003), 521–554.
Nikhil Swamy, Cédric Fournet, Aseem Rastogi, Karthikeyan Bhargavan, Juan Chen, Pierre-Yves Strub, and Gavin M. Bierman. 2014. Gradual typing
embedded securely in JavaScript. In ACM Symposium on Principles of Programming Languages (POPL), San Diego, California. 425–438.
Satish Thatte. 1990. Quasi-static typing. In ACM Symposium on Principles of Programming Languages (POPL). 367–381.
Sam Tobin-Hochstadt and Matthias Felleisen. 2006. Interlanguage Migration: From Scripts to Programs. In Dynamic Languages Symposium (DLS).
964–974.
Sam Tobin-Hochstadt and Matthias Felleisen. 2008. The Design and Implementation of Typed Scheme. In ACM Symposium on Principles of
Programming Languages (POPL), San Francisco, California.
Sam Tobin-Hochstadt and Matthias Felleisen. 2010. Logical Types for Untyped Languages. In International Conference on Functional Programming
(ICFP). ACM, 117–128.
Jonathan Turner. 2014. TypeScript and the Road to 2.0. (October 2014). https://blogs.msdn.microsoft.com/typescript/2014/10/22/
typescript-and-the-road-to-2-0/
Julien Verlaguet. 2013. Facebook: Analyzing PHP statically. In Commercial Users of Functional Programming (CUFP).
Philip Wadler. 1989. Theorems for free!. In ACM Symposium on Functional Programming Languages and Computer Architecture (FPCA).
Philip Wadler and Robert Bruce Findler. 2009. Well-typed programs can’t be blamed. In European Symposium on Programming (ESOP). 1–16.
Andrew K. Wright. 1995. Simple Imperative Polymorphism. Higher-Order and Symbolic Computation 8, 4 (Dec. 1995), 343–355.

23

You might also like