Part III Chapter 15: Subtyping Subsumption Subtype relation Properties of subtyping and typing Subtyping and other features Intersection and union types
Subtyping
Motivation With the usual typing rule for applications the term is not well typed.
Motivation With the usual typing rule for applications the term is not well typed. This is silly: all we re doing is passing the function a better argument than it needs.
Subsumption More generally: some types are better than others, in the sense that a value of one can always safely be used where a value of the other is expected. We can formalize this intuition by introducing:
Subsumption More generally: some types are better than others, in the sense that a value of one can always safely be used where a value of the other is expected. We can formalize this intuition by introducing: 1. a subtyping relation between types, written S <: T
Subsumption More generally: some types are better than others, in the sense that a value of one can always safely be used where a value of the other is expected. We can formalize this intuition by introducing: 1. a subtyping relation between types, written S <: T 2. a rule of subsumption stating that, if S <: T, then any value of type S can also be regarded as having type T
Subsumption More generally: some types are better than others, in the sense that a value of one can always safely be used where a value of the other is expected. We can formalize this intuition by introducing: 1. a subtyping relation between types, written S <: T 2. a rule of subsumption stating that, if S <: T, then any value of type S can also be regarded as having type T Principle of safe substitution
Subtyping Intuitions: S <: T means... An element of S may safely be used wherever an element of T is expected. (Official.)
Subtyping Intuitions: S <: T means... An element of S may safely be used wherever an element of T is expected. (Official.) S is better than T S is a subset of T S is more informative / richer than T.
Example We will define subtyping between record types so that, for example {x: Nat, y: Nat} <: {x: Nat} So, by subsumption, {x = 0, y = 1} {x: Nat}
Example We will define subtyping between record types so that, for example {x: Nat, y: Nat} <: {x: Nat} So, by subsumption, {x = 0, y = 1} {x: Nat} and hence (λr: {x: Nat}. r. x) {x = 0, y = 1} is well typed.
The Subtype Relation: Records Width subtyping (forgetting fields on the right): {l i : T i i 1..n+k } <: l i : T i i 1..n (S-RcdWidth) Intuition: {x: Nat} is the type of all records with at least a numeric x field.
The Subtype Relation: Records Width subtyping (forgetting fields on the right): {l i : T i i 1..n+k } <: l i : T i i 1..n (S-RcdWidth) Intuition: {x: Nat} is the type of all records with at least a numeric x field. Note that the record type with more fields is a subtype of the record type with fewer fields. Reason: the type with more fields places a stronger constraint on values, so it describes fewer values.
The Subtype Relation: Records Permutation of fields:
Order of fields in Records The order of fields in a record does not make any difference to how we can safely use it, since the only thing that we can do with records (projecting their fields) is insensitive to the order of fields.
Order of fields in Records The order of fields in a record does not make any difference to how we can safely use it, since the only thing that we can do with records (projecting their fields) is insensitive to the order of fields. S-RcdPerm tells us that {c:top, b: Bool, a: Nat} <: {a: Nat, b: Bool, c:top} and {a: Nat, b: Bool, c:top} <: {c:top, b: Bool, a: Nat}
The Subtype Relation: Records Permutation of fields: By using S-RcdPerm together with S-RcdWidth and S-Trans allows us to drop arbitrary fields within records.
The Subtype Relation: Records Depth subtyping within fields: The types of individual fields may change, as long as the type of each corresponding field in the two records are in the subtype relation.
Example
Example We can also use S-RcdDepth to refine the type of just a single record field (instead of refining every field), by using S-RefL to obtain trivial subtyping derivations for other fields. S RRRRRRRR S RRRR a: NNN, b: NNN <: a: NNN m: NNN <: m: NNN x: a: NNN, b: NNN, y: m: NNN <: {x: a: NNN, y: m: NNN } S RcdDepth
Variations Real languages often choose not to adopt all of these record subtyping rules. For example, in Java, A subclass may not change the argument or result types of a method of its superclass (i.e., no depth subtyping) Each class has just one superclass ( single inheritance of classes) each class member (field or method) can be assigned a single index, adding new indices on the right as more members are added in subclasses (i.e., no permutation for classes) A class may implement multiple interfaces ( multiple inheritance of interfaces) I.e., permutation is allowed for interfaces.
The Subtype Relation: Arrow types
The Subtype Relation: Arrow types Note the order of T 1 and S 1 in the first premise. The subtype relation is contravariant in the left-hand sides of arrows and covariant in the right-hand sides.
The Subtype Relation: Arrow types Note the order of T 1 and S 1 in the first premise. The subtype relation is contravariant in the left-hand sides of arrows and covariant in the right-hand sides. Intuition: if we have a function f of type S 1 S 2, then we know that f accepts elements of type S 1 ; clearly, f will also accept elements of any subtype T 1 of S 1. The type of f also tells us that it returns elements of type S 2 ; we can also view these results belonging to any supertype T 2 of S 2. That is, any function f of type S 1 S 2 can also be viewed as having type T 1 T 2.
The Subtype Relation: Top It is convenient to have a type that is a supertype of every type. We introduce a new type constant Top, plus a rule that makes Top a maximum element of the subtype relation.
The Subtype Relation: Top It is convenient to have a type that is a supertype of every type. We introduce a new type constant Top, plus a rule that makes Top a maximum element of the subtype relation. Cf. Object in Java.
Subtype Relation: General rules
Subtype Relation
Properties of Subtyping
Safety Statements of progress and preservation theorems are unchanged from λ.
Safety Statements of progress and preservation theorems are unchanged from λ. Proofs become a bit more involved, because the typing relation is no longer syntax directed. Given a derivation, we don t always know what rule was used in the last step. The rule T-SUB could appear anywhere.
Syntax-directed rules When we say a set of rules is syntax-directed we mean two things: 1. There is exactly one rule in the set that applies to each syntactic form. (We can tell by the syntax of a term which rule to use.) In order to derive a type for t 1 t 2, we must use T-App. 2. We don't have to guess" an input (or output) for any rule. To derive a type for t 1 t 2, we need to derive a type for t 1 and a type for t 2.
Preservation Theorem: If Γ t: T aaa t t, tttt Γ t T. Proof: By induction on typing derivations. Which cases are likely to be hard?
Subsumption case Case T-Sub: t S S <: T By the induction hypothesis, Γ t S. By T-Sub, Γ t. Not hard!
Application case Case T-APP : t = t 1 t 2 Γ t 1 : T 11 T 12 Γ t 2 : T 11 T = T 12 By the inversion lemma for evaluation, there are three rules by which t t can be derived: E-APP1, E-APP2, and E-APPABS. Proceed by cases.
Application case Case T-APP : t = t 1 t 2 Γ t 1 : T 11 T 12 Γ t 2 : T 11 T = T 12 By the inversion lemma for evaluation, there are three rules by which t t can be derived: E-APP1, E-APP2, and E-APPABS. Proceed by cases. Subcase E-APP1: t 1 t 1 t = t 1 t 2 The result follows from the induction hypothesis and T- APP.
Application case Case T-APP : t = t 1 t 2 Γ t 1 : T 11 T 12 Γ t 2 : T 11 T = T 12 Subcase E-APP2 : t 1 = v 1 t 2 t 2 t = v 1 t 2 Similar.
Application case Case T-APP: t = t 1 t 2 Γ t 1 : T 11 T 12 Γ t 2 : T 11 T = T 12 Subcase E-APPABS : t 1 = λx: S 11. t 12 t 2 = v 2 t = [x v 2 ] t 12 By the inversion lemma for the typing relation... T 11 <: S 11 and Γ, x: S 11 t 12 : T 12. By T-Sub, Γ t 2 : S 11. By the substitution lemma, Γ t : T 12.
Inversion Lemma for Typing Lemma: If Γ λx: S 1. s 2 : T 1 T 2, then T 1 <: S 1 and Γ, x: S 1 s 2 : T 2.
Inversion Lemma for Typing Lemma: If Γ λx: S 1. s 2 : T 1 T 2, then T 1 <: S 1 and Γ, x: S 1 s 2 : T 2. Proof: Induction on typing derivations. Case T Sub: λx: S 1. s 2 : U U: T 1 T 2 We want to say By the induction hypothesis..., but the IH does not apply (we do not know that U is an arrow type). Need another lemma... Lemma: If U <: T 1 T 2, then U has the form: U 1 U 2, with T 1 <: U 1 and U 2 <: T 2. (Proof: by induction on subtyping derivations.)
Inversion Lemma for Typing By this lemma, we know U = U 1 U 2, with T 1 <: U 1 and U 2 <: T 2. The IH now applies, yielding U 1 <: S 1 and Γ, x: S 1 s 2 : U 2. From U 1 <: S 1 and T 1 <: U 1, rule S-Trans gives T 1 <: S 1. From Γ, x: S 1 s 2 : U 2 and U 2 <: T 2, rule T-Sub gives Γ, x: S 1 s 2 : T 2, and we are done
Subtyping with Other Features
Ascription and Casting Ordinary ascription:
Ascription and Casting Ordinary ascription: Casting (cf. Java):
Subtyping and Variants
Subtyping and Lists i.e., List is a covariant type constructor.
Subtyping and References i.e., Ref is not a covariant (nor a contravariant) type constructor.
Subtyping and References i.e., Ref is not a covariant (nor a contravariant) type constructor. Why? When a reference is read, the context expects a T 1, so if S 1 <: T 1 then an S 1 is ok.
Subtyping and References i.e., Ref is not a covariant (nor a contravariant) type constructor. Why? When a reference is read, the context expects a T 1, so if S 1 <: T 1 then an S 1 is ok. When a reference is written, the context provides a T 1 and if the actual type of the reference is Ref S 1, someone else may use the T 1 as an S 1. So we need T 1 <: S 1.
Subtyping and Arrays Similarly... This is regarded (even by the Java designers) as a mistake in the design.
References again Observation: a value of type Ref T can be used in two different ways: as a source for values of type T and as a sink for values of type T.
References again Observation: a value of type Ref T can be used in two different ways: as a source for values of type T and as a sink for values of type T. Idea:Split Ref T into three parts: Source T: reference cell with read capability Sink T: reference cell with write capability Ref T: cell with both capabilities
Modified Typing Rules
Subtyping rules
Capabilities Other kinds of capabilities (e.g., send and receive capabilities on communication channels, encrypt/decrypt capabilities of cryptographic keys,...) can be treated similarly.
Intersection and Union Types
Intersection Types The inhabitants of T 1 T 2 are terms belonging to both S and T i.e., T 1 T 2 is an order-theoretic meet (greatest lower bound) of T 1 and T 2.
Intersection Types Intersection types permit a very flexible form of finitary overloading. This form of overloading is extremely powerful. Every strongly normalizing untyped lambda-term can be typed in the simply typed lambda-calculus with intersection types. type reconstruction problem is undecidable Intersection types have not been used much in language designs (too powerful!), but are being intensively investigated as type systems for intermediate languages in highly optimizing compilers (cf. Church project).
Union types Union types are also useful. T 1 T 2 is an untagged (non-disjoint) union of T 1 and T 2. No tags : no case construct. The only operations we can safely perform on elements of T 1 T 2 are ones that make sense for both T 1 and T 2. N.b: untagged union types in C are a source of type safety violations precisely because they ignores this restriction, allowing any operation on an element of T 1 T 2 that makes sense for either T 1 or T 2. Union types are being used recently in type systems for XML processing languages (cf. Xduce, Xtatic).
Varieties of Polymorphism Parametric polymorphism (ML-style) Subtype polymorphism (OO-style) Ad-hoc polymorphism (overloading)
Homework Read chapter 14 & 15 Read and chew over the codes of chap 17. HW: 14.3.1, 15.5.2