Lecture Notes On Subtyping: 15-312: Foundations of Programming Languages Frank Pfenning October 19, 2004
Lecture Notes On Subtyping: 15-312: Foundations of Programming Languages Frank Pfenning October 19, 2004
Subtyping
Lecture 14
October 19, 2004
This can be refined into two more specific statements, depending on the
form of subtyping used.
f : τ1 ≤ τ2 g : τ2 ≤ τ3
ref l trans
λx.x : τ ≤ τ λx.g(f (x)) : τ1 ≤ τ3
The three laws we have are essentially all the general laws that can be
formulated in this manner. Coherence is stated in a way that is similar to a
substitution principle.
because the first argument 2 can be coerced to the floating point number
2.0 by applying itof. Concretely:
This alternative compilation will behave identically to the first one, itof
and λy.itof((λx.x)(y)) are observationally equivalent. To see this, apply
both sides to a value v. Then the one side yiels itof(v), the other side
The fact that the particular chosen typing derivation does not affect the
behavior of the compiled expressions (where coercions are explicit) is the
subject of the coherence theorem for a language. This is a more precise ex-
pression of the “uniqueness” required in the defining property for coercive
subtyping.
At this point we have general laws for typing (subsumption) and sub-
typing (reflexivity and transitivity). But how does subtyping interact with
pairs, functions, and other constructs? We start with pairs. We can coerce a
value of type τ1 ×τ2 to a value of type σ1 ×σ2 if we can coerce the individual
components appropriately. That is:
τ1 ≤ σ 1 τ2 ≤ σ 2
τ1 × τ2 ≤ σ 1 × σ 2
f1 : τ1 ≤ σ1 f2 : τ2 ≤ σ2
λp.pair(f1 (fst(p)), f2 (snd(p))) : τ1 × τ2 ≤ σ1 × σ2
because we can obtain a function of the type on the right from a function
on the left by coercing the argument:
σ 1 ≤ τ1 τ2 ≤ σ 2
τ1 → τ2 ≤ σ 1 → σ 2
The fact that the subtyping relationship flips in the left premise is called
contravariance. We say that function subtyping is contravariant in the argu-
ment and covariant in the result. Subtyping of pairs, on the other hand, is
covariant in both components.
Mutable reference can be neither covariant nor contravariant. As simple
counterexamples, consider the following pieces of code.
The first one assumes that τ ref ≤ σ ref if σ ≤ τ , that is reference sub-
typing is contravariant.
τ singleton ≤ σ singleton