Docsity
Docsity

Prepare for your exams
Prepare for your exams

Study with the several resources on Docsity


Earn points to download
Earn points to download

Earn points by helping other students or get them with a premium plan


Guidelines and tips
Guidelines and tips

F-Bounded Quantification: Polymorphism with Recursive Object Types, Study notes of Object Oriented Programming

The use of F-bounded quantification, a form of polymorphism, in object-oriented programming with recursive types. The authors argue that bounded quantification, which works well for non-recursive types, is not sufficient for recursive types. F-bounded quantification is introduced as a solution, allowing polymorphic functions to work with objects of different recursive types. The document also touches upon the connection between F-bounded quantification and F-coalgebras.

What you will learn

  • What is F-bounded quantification and how does it differ from regular bounded quantification?
  • How does F-bounded quantification help with polymorphic functions in object-oriented programming with recursive types?
  • What is the connection between F-bounded quantification and F-coalgebras?

Typology: Study notes

2021/2022

Uploaded on 09/27/2022

kitriotak
kitriotak 🇮🇳

4.5

(13)

220 documents

1 / 8

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
F-Bounded Polymorphism
for Object-Oriented Programming
Peter Canning, William Cook, Walter Hill, Walter Olthoff
Hewlett-Packard Laboratories
P.O. Box 10490, Palo Alto, CA 94303-0971
John C. Mitchell
Department of Computer Science
Stanford University, Stanford, CA 94309
Abstract
Bounded quantification was introduced by Cardelli and
Wegner as a means of typing functions that operate uni-
formly over all subtypes of a given type. They defined
a simple “object” model and used bounded quantifica-
tion to type-check functions that make sense on all ob-
jects having a specified set of “attributes.” A more re-
alistic presentation of object-oriented languages would
allow objects that are elements of recursively-defined
types. In this context, bounded quantification no longer
serves its intended purpose. It is easy to find func-
tions that makes sense on all objects having a speci-
fied set of methods, but which cannot be typed in the
Cardelli-Wegner system. To provide a basis for typed
polymorphic functions in object-oriented languages, we
introduce F-bounded quantification. Some applications
of F-bounded quantification are presented and seman-
tic issues are discussed. Although our original moti-
vation was to type polymorphic functions over objects,
F-bounded quantification is a general form of polymor-
phism that seems useful whenever recursive type defin-
itions and subtyping are used.
1 Introduction
Although object-oriented programming has attracted
increasing interest in recent years, the development
of polymorphic type systems for object-oriented lan-
guages has progressed slowly. One reason is that ob ject-
oriented languages are often described using terminol-
ogy that sets them apart from functional languages. In
addition, there has been a lack of formal models for
object-oriented languages. As a result, it has been
difficult to see how practical polymorphic type sys-
tems should be adapted for typing object-oriented con-
structs. In Cardelli’s seminal paper [8], record subtyp-
ing was identified as an important form of polymor-
phism in object-oriented programs. This lead to the
development of “bounded quantification” in [7]. If we
view objects as elements of non-recursive record types,
then bounded quantification provides a useful form of
polymorphism over objects. However, a more sophis-
ticated presentation of object-oriented constructs (as
in [5, 11, 10]) would allow objects that are elements
of recursively-defined types. With recursive types, the
Cardelli-Wegner form of bounded quantification is not
sufficiently expressive to meet its original goal.
F-bounded quantification is a natural extension of
bounded quantification that seems particularly useful
in connection with recursive types. The essential idea
may be illustrated by comparison with Cardelli-Wegner
bounded quantification. Using for the subtype re-
lation, a simple example of a bounded-quantified type
is the type tτ. t t. This is the type of func-
tions which map tto t, for every subtype tof τ. In
a setting where all structurally similar objects belong
to subtypes of a given type, many useful polymorphic
functions will have bounded quantified types. For ex-
ample, if we type an object by listing its methods and
their types, an object with a print method may have
type {. . . , print:void string, . . .}, indicating that the
method print produces a print representation of the
object. In the view of subtyping presented in [8],
every type of this form will be a subtype of the type
{print:void string}of objects having only a print
method. For example,
{A:int void,print:void string}
{print:void string}.
A function taking a list of printable objects, a string and
returning an object whose print representation matches
the given string will have the bounded-quantified type
t {print:string}.list[t]string t.
1
pf3
pf4
pf5
pf8

Partial preview of the text

Download F-Bounded Quantification: Polymorphism with Recursive Object Types and more Study notes Object Oriented Programming in PDF only on Docsity!

F-Bounded Polymorphism

for Object-Oriented Programming

Peter Canning, William Cook, Walter Hill, Walter Olthoff

Hewlett-Packard Laboratories

P.O. Box 10490, Palo Alto, CA 94303-

John C. Mitchell

Department of Computer Science

Stanford University, Stanford, CA 94309

Abstract

Bounded quantification was introduced by Cardelli and Wegner as a means of typing functions that operate uni- formly over all subtypes of a given type. They defined a simple “object” model and used bounded quantifica- tion to type-check functions that make sense on all ob- jects having a specified set of “attributes.” A more re- alistic presentation of object-oriented languages would allow objects that are elements of recursively-defined types. In this context, bounded quantification no longer serves its intended purpose. It is easy to find func- tions that makes sense on all objects having a speci- fied set of methods, but which cannot be typed in the Cardelli-Wegner system. To provide a basis for typed polymorphic functions in object-oriented languages, we introduce F-bounded quantification. Some applications of F-bounded quantification are presented and seman- tic issues are discussed. Although our original moti- vation was to type polymorphic functions over objects, F-bounded quantification is a general form of polymor- phism that seems useful whenever recursive type defin- itions and subtyping are used.

1 Introduction

Although object-oriented programming has attracted increasing interest in recent years, the development of polymorphic type systems for object-oriented lan- guages has progressed slowly. One reason is that object- oriented languages are often described using terminol- ogy that sets them apart from functional languages. In addition, there has been a lack of formal models for object-oriented languages. As a result, it has been difficult to see how practical polymorphic type sys- tems should be adapted for typing object-oriented con- structs. In Cardelli’s seminal paper [8], record subtyp-

ing was identified as an important form of polymor- phism in object-oriented programs. This lead to the development of “bounded quantification” in [7]. If we view objects as elements of non-recursive record types, then bounded quantification provides a useful form of polymorphism over objects. However, a more sophis- ticated presentation of object-oriented constructs (as in [5, 11, 10]) would allow objects that are elements of recursively-defined types. With recursive types, the Cardelli-Wegner form of bounded quantification is not sufficiently expressive to meet its original goal. F-bounded quantification is a natural extension of bounded quantification that seems particularly useful in connection with recursive types. The essential idea may be illustrated by comparison with Cardelli-Wegner bounded quantification. Using “⊆” for the subtype re- lation, a simple example of a bounded-quantified type is the type ∀t ⊆ τ. t → t. This is the type of func- tions which map t to t, for every subtype t of τ. In a setting where all structurally similar objects belong to subtypes of a given type, many useful polymorphic functions will have bounded quantified types. For ex- ample, if we type an object by listing its methods and their types, an object with a print method may have type {... , print: void → string,.. .}, indicating that the method print produces a print representation of the object. In the view of subtyping presented in [8], every type of this form will be a subtype of the type {print: void → string} of objects having only a print method. For example,

{A: int → void, print: void → string} ⊆ {print: void → string}.

A function taking a list of printable objects, a string and returning an object whose print representation matches the given string will have the bounded-quantified type ∀t ⊆ {print: string}. list[t] → string → t.

The flexibility of bounded quantification is dramati- cally reduced when objects belong to recursively-defined types. For example, consider the type

PartialOrder = { lesseq: PartialOrder → Bool }.

Each object of this type has a method lesseq which may be applied to another object of the same type. We in- tend the result of x.lesseq(y) to be true if x does not exceed y in some ordering, and false otherwise. Using lesseq, it should be possible to sort lists of PartialOrder elements, for example. We may easily write a sort- ing function with type ∀t ⊆ PartialOrder. list[t] → list[t]. However, as we shall see later in the paper, object- oriented versions of the usual partially-ordered types such as integers are not subtypes of PartialOrder. There- fore, our generic sorting function cannot be used in the way we might expect. To solve this problem and related difficulties with other forms of recursive types we intro- duce a generalization of bounded quantification which we call F-bounded quantification, for want of better ter- minology. For the example at hand, consider the func- tion F from types to types given by

F[t] = { lesseq: t → bool }.

We may write a polymorphic sorting function of type ∀t ⊆ F[t].list[t] → list[t], where this function is defined on any type t such that t ⊆ F[t]. Since integer ⊆ F[integer], as explained in Section 3.3, we may apply such a sorting function to lists of integers or lists of any other type of objects having lesseq methods. One practical application of F-bounded quantification is for understanding some problems in the type system of the Eiffel programming language [18]. Eiffel intro- duces a special type expression, like Current, to represent recursion at the type level. Like Current always repre- sents the ‘current class’: in a class P it simply stands for P , but when this class is inherited by a subclass C, like Current in an inherited attribute is reinterpreted to stand for the subclass C. The subclasses of such a class are usefully understood as having interfaces that sat- isfy an F-bound. However, as mentioned above, there is no necessary subtype relation among types satisfying an F-bound. This analysis explains some insecurities in the Eiffel type-system, which always allows subclasses to act as if they are subtypes of their parents. Further details are given in [12], along with some suggestions for correcting Eiffel’s problems using the results in this pa- per. The error in the Eiffel type system illustrates the subtlety involved in designing flexible and sound type systems for object-oriented languages. Another type system with a generalized form of bounded quantification is presented by Curtis [13]. In this system, arbitrary collections of subtype constraints

may be imposed on the quantified type variable. Thus Curtis’ system subsumes our more modest proposal. However, we believe that our form of quantification is both sufficient to type-check practically useful object- oriented programs, and more tractable. Some evidence for the naturality of F-bounded quantification is the intriguing connection with F-coalgebras, the dual of a standard construction in the category-theoretic charac- terization of type recursion [22]. The next section surveys relevant background on strongly-typed object-oriented programming. Section 3 illustrates in detail problems with previous techniques for dealing with recursive object types. Section 4 intro- duces F-bounded quantification and demonstrates that it solves the typing problems presented in the previous section. some speculative observations on the semantic aspects of F-bounded quantification. Section 6 summa- rizes our contribution and indicates directions for future research.

2 Background

2.1 Objects, Records and Recursive

Types

A fundamental premise underlying most models of object-oriented programming is that objects may be re- garded as record whose components are functions rep- resenting methods [8, 7, 25, 11, 5]. In this model, “mes- sage sending” is implemented by simple component se- lection. Record types are used to describe the protocols [14] or interfaces of objects. A record type is a map- ping of labels to types. A record consisting of labels l 1 ,... , lj with associated values in types σ 1 ,... , σj has type {l 1 : σ 1 ,... , lj : σj }. The fields of the record type describe messages together with the types of their ar- guments and return values. This view is adopted in the programming languages Amber [6], Modula-3 [10], and TS [17]. Even the very simplest “textbook” examples from object-oriented programming produce recursively- defined record types [21, 1, 6, 16, 10]. For example, the type of a planar point with four methods is defined recursively as follows. Point = { x : void → Real, y : void → Real, move : Real × Real → Point, equal : Point → Boolean } The body of the recursive type is a record type indi- cated by braces {.. .}. The use of Point in the return

3 Recursive Types and Bounded

Quantification

3.1 Introduction

In this section we investigate the use of bounded quanti- fication in polymorphic functions over objects with re- cursive types. We show that bounded quantification does not provide the same degree of flexibility in the presence of recursion as it does for non-recursive types. Two kinds of problems are identified, depending upon the location of the recursion variable within the recur- sive type. In describing the two possibilities, it is useful to adopt the standard notion of “polarity” from logic. In a type expression σ → τ , the subexpression τ oc- curs positively and the subexpression σ negatively. If σ′ occurs with positive or negative polarity in σ, then this occurrence will have the opposite polarity in σ → τ. A subexpression of τ will have the same polarity in σ → τ. For example, t is positive in (t → σ) → τ but negative in t → (ρ → τ ). Polarity is preserved in record type expressions, so that t is positive and s is negative in {put: t → void, get: void → s}.

3.2 Subtyping and Positive Recursion

When the recursion variable of a recursive type appears positively, subtyping does not ensure the intuitively ex- pected typing behavior. Consider the recursive type Movable introduced above. The recursion variable mv in Movable only occurs positively.

Movable = Rec mv. { move: Real × Real → mv }

It is reasonable to define a function, translate, that moves a movable value one unit in both directions:

translate = fun(x:Movable) x.move(1.0, 1.0)

Although this function works for any value whose type is a subtype of Movable, the result of the function appli- cation is always of type Movable, according to the typing rules of [7]. It would be preferable to have a polymor- phic translate which, for any subtype of t of Movable, takes argument of type t and return a value of the same type. However, an easy semantic argument shows that translate as defined above does not have the type

translate : ∀r ⊆ Movable. r → r

To see this, consider the type

R = { move: Real × Real → Movable, other: A }

It is easy to see that R is a proper subtype of Movable. However, if we apply translate to an object of type R, we obtain an object of type Movable, not R. Thus the best we can say with bounded quantification is

translate : ∀r ⊆ Movable. r → Movable

which is no more general than the ordinary function type Movable → Movable. The careful reader may notice that translate can in fact be typed without using bounded quantification, giv- ing

translate : ∀t. { move: Real × Real → t } → t

However, this should not be regarded as a defect in our presentation; this works only because translate is an un- usually simple example. An essential aspect of translate is that the parameter x only occurs once in the body of the function, where we access the move field. In a more complicated function like

choose = fun(b:bool) fun(x:Movable) if b then x.move(1.0, 1.0) else x

in which the method is called and the object returned, the simple typing without bounded quantification is not possible.

3.3 Subtyping and Negative Recursion

For a recursive type with a negative recursion-variable, the intuitive concept of ‘adding fields’ to produce sub- types does not work: the resulting types are not sub- types of the original recursive type. Consequently, bounded quantification cannot be used to quantify over these types. To illustrate, assume we want to define a polymorphic minimum function on a PartialOrder type that describes values with a comparison method:

PartialOrder = Rec po. { lesseq: po → bool }

minimum : ∀t ⊆ PartialOrder. t → t → t

The minimum function should return the lesser of its two arguments, determined by asking the first argument to compare itself with the second. Intuitively, values of type Number or String should be admissible arguments for the polymorphic minimum, since they both have a lesseq operation as required. The type Number, in our view of object-oriented languages, is a recursively de- fined record type:

Number = Rec num. {... , lesseq: num → bool,... }

However, the polymorphic application minimum [Number] is type-incorrect, because Number is not a sub- type of PartialOrder. If we try to derive Number ⊆ PartialOrder by unrolling the two types we obtain

{... , lesseq: Number → bool,... } ⊆ { lesseq: PartialOrder → bool }

which requires PartialOrder ⊆ Number. This is con- trary to what we wanted to show, indicating that Num- ber ⊆ PartialOrder is not derivable unless Number = PartialOrder. One type that is a subtype of PartialOrder is

Rec t. {... , lesseq: PartialOrder → bool,... }

An object of this type could be compared (using lesseq) with any other value of type PartialOrder, but since Par- tialOrder does not provide any fields on which to base this comparison, objects of this type have little practi- cal value. In situations where more fields are present such types may be useful, but the problem remains that subtyping cannot capture the intuitive polymorphism desired for minimum.

4 F-bounded Quantification

4.1 Introduction

F-bounded quantification allows the practical examples given above to be type-checked with intuitively desirable types. We say that a universally quantified type is F- bounded if it has the form

∀t ⊆ F [t].σ

where F [t] is an expression, generally containing the type variable t. The semantics of F-bounded quantifi- cation are discussed briefly in Section 5. F-bounded polymorphic types differ from ordinary bounded types by binding the type variable in both the result-type σ and the type bound F [t]. If F [t] is a type of the form F [t] = {ai: σi[t]}, then the con- dition A ⊆ F [A] says, in effect, that A must have the methods ai and these methods must have ar- guments as specified by σi[A], which are defined in terms of A. Thus A will often be a recursive type, suggesting that F-bounded quantification is closely related to type recursion. But bounded quantifi- cation ∀t ⊆ (Rec r.F [r]).σ(t) over a recursive type is very different from the F-bounded quantification ∀t ⊆ F [t].σ(t) over the type-function F that defines the recursive type, as shown in the following sections.

4.2 Positive Recursion

As we saw in Section 3.2, the polymorphic application translate[Point] produces a function of type Point → Movable, rather than Point → Point as desired. A simple type derivation will both motivate the definition of F-bounded quantification, and show how it can be used to achieve the desired typing of translate.

In the this example we ‘work backwards’ to derive the F-bounded constraint from the typing problem posed by translate. The problem is to derive a condition on a type t so that for any variable x of type t, x.move(1.0, 1.0) has type t. In the following discussion we use the subtype rules of [9] or [19]. We are looking for the minimal condition on t such that the following typing can be derived:

x : t ` x.move(1.0, 1.0) : t

By the application (APP) and selection (SEL) rules, this reduces to

x : t ` x : { move : Real × Real → t }

Using the subtyping rule we then derive

τ ⊆ {move: Real× Real → t} x: t ` x: τ

Since the type τ does not occur in any other assumption, we may simplify to the requirement

t ⊆ { move : Real × Real → t },

which cannot be proved without additional assump- tions. Expressing this condition as t ⊆ F-Movable[t], where

F-Movable[t] = { move : Real × Real → t }

it is clear that this condition fits the format of F- bounded quantification. Motivated by the preceding discussion, we define the F-bounded polymorphic func- tion:

translate = Fun[ t ⊆ F-Movable[t] ] fun(x:t) x.move(1.0, 1.0)

with F-bounded polymorphic type

translate : ∀t ⊆ F-Movable[t]. t → t

Since Point ⊆ F-Movable[Point], the application trans- late[Point] is type-correct, and has result of type Point → Point. Of course translate will also work for other types that satisfy the constraint t ⊆ F-Movable[t], such as ColoredPoint, defined as follows.

ColoredPoint = Rec pnt. { x : void → Real, y : void → Real, c : void → Color, move : Real × Real → pnt, }

term must translate into provably equivalent terms in the calculus with explicit coercions. Coherence is a dif- ficult technical property, and we have not verified it for our calculus. Regardless of how we interpret a subtyping assertion A ⊆ B, it is clear that this assertion implies some kind of map from A to B. This simple observation leads us to some interesting connections between F-bounded quantification and the standard category-theoretic ma- chinery associated with recursive type definitions [22]. To begin with, in most semantics of recursive types, it is possible to extend type functions defined by type expressions to functors (maps on types and functions) over some category (perhaps with a more limited choice of functions than we actually define in programming). If we have a functor F and wish to find a type t sat- isfying t = F [t], where = means isomorphism, then it suffices to find an initial F-algebra, where an F-algebra is a pair 〈t, f 〉 with f : F [t] → t. It is an easy exercise to prove that if 〈t, f 〉 is an initial F-algebra, then f has a two-sided inverse f −^1. The dual of an F-algebra is an F-coalgebra, which is a pair 〈t, f 〉 with f : t → F [t]. The argument showing that an initial F-algebra is a solution to t = F [t] also shows that the final F-coalgebra satisfies t = F [t]. In F-bounded polymorphism, we quantify over all types t with t ⊆ F [t]. Taking into account that t ⊆ F [t] implies some kind of map from t to F [t], this means we are essentially quantifying over pairs 〈t, f 〉 with f : t → F [t], or some family of F-coalgebras. (The quantification over some family of maps t → F [t] is made explicit in the translation in [2].) Since the recur- sive type Rec t. F [t] may be regarded as a particular F- coalgebra, this suggests that F-bounded polymorphism involves quantification over a category whose objects are properly regarded as “generalizations” of the recursive type Rec t. F [t]. One way of seeing why this provides useful poly- morphism in object-oriented languages is to consider the typing rules associated with recursive types. If t = Rec t. F [t], then we have an “introduction” rule saying that if an expression e: F [t] then e: t. The “elimi- nation” rule gives the converse: if e: t then e: F [t]. These rules are based on the two directions of the isomor- phism t = F [t]. If A satisfies the F-bounded condition A ⊆ F [A], then A is a type which has the “elimination” typing rule associated with Rec t. F [t], but not neces- sarily the associated “introduction” rule. This is a pre- cise way of saying that at type A satisfying A ⊆ F [A] shares “structural similarity” with the recursive type Rec t. F [t]. In general, for recursive types of the form

Rec t.{method 1 : σ 1 ,... , methodk: σk}

it seems that only the “elimination” is needed to make

meaningful use of object with this type. Hence F- bounded quantification seems to be “exactly what we need” in order to type polymorphic functions over ob- jects with recursive types.

6 Conclusion

We have identified a generalization of bounded quanti- fication, called F-bounded quantification, in which the bound type variable may occur within the bound. We argue that F-bounded quantification is useful for typing programs involving recursive types: it allows quantifi- cation over types that are “structurally similar” to the recursive type Rec t. F [t]. As directions for future work, we note that F-bounded quantification is closely related to inclusion for single- sorted algebraic signatures. F-bounded quantification captures the notion of adding more operations to a re- cursive type while preserving the recursive structure of the type. F-bounded quantification also has an impact on the relation between inheritance and subtyping in object- oriented programs. As noted in Section 4.3, two types t 1 and t 2 may satisfy an F-bound (t 1 ⊆ F [t 1 ] and t 2 ⊆ F [t 2 ]) but not be in a subtype relation (neither t 1 ⊆ t 2 or t 2 ⊆ t 1 ). This means that a F-bounded function may be applied to (or “inherited” by) objects with incomparable types, demonstrating that the inher- itance hierarchy is distinct from the subtype hierarchy [23]. In the Abel project at HP Labs, we are explor- ing the consequences of this separation on programming language design.

References

[1] Alan H. Borning and D. H. H. Ingalls. Multiple inheritance in smalltalk-80. pages 234–237, 1982.

[2] Val Breazu-Tannen, Thierry Coquand, Carl A. Gunter, and Andre Scedrov. Inheritance as implicit coercion. Inf. Comput., 93(1):172–221, 1991.

[3] K. B. Bruce, A. R. Meyer, and J. C. Michell. The semantics of second-order lambda calculus. Infor- mation and Control, 1986.

[4] Kim B. Bruce and Giuseppe Longo. A mod- est model of records, inheritance, and unbounded quantification. Inf. Comput., 87(1-2):196–240,

[5] Peter Canning, William Cook, Walt Hill, John Mitchell, and Walter Olthoff. F-bounded polymor- phism for object-oriented programming. In Proc. of

Conf. on Functional Programming Languages and Computer Architecture, pages 273–280, 1989.

[6] L. Cardelli. Amber. In Combinators and Func- tional Programming Languages, volume 242 of Lec- ture Notes in Computer Science, 1986.

[7] L. Cardelli and P. Wegner. On understanding types, data abstraction, and polymorphism. Com- puting Surveys, 17(4):471–522, 1986.

[8] Luca Cardelli. A semantics of multiple inheritance. In Semantics of Data Types, volume 173 of Lecture Notes in Computer Science, pages 51–68. Springer- Verlag, 1984.

[9] Luca Cardelli. Structural subtyping and the no- tion of power type. In Proc. of the ACM Symp. on Principles of Programming Languages, pages 70–

  1. ACM, 1988.

[10] Luca Cardelli, James Donahue, Lucille Glass- man, Mick Jordan, Bill Kalsow, and Greg Nelson. Modula-3 report (revised). Technical Report 52, Digital Equipment Corporation Systems Research Center, December 1989.

[11] William Cook. A Denotational Semantics of Inher- itance. PhD thesis, Brown University, 1989.

[12] William Cook. A proposal for making Eiffel type- safe. In Proc. European Conf. on Object-Oriented Programming, pages 57–70. British Computing So- ciety Workshop Series, 1989. Also in The Computer Journal, 32(4):305–311, 1989.

[13] Pavel Curtis. Constrained qualification in polymor- phic type analysis. PhD thesis, Ithaca, NY, USA,

[14] A. Goldberg and D. Robson. Smalltalk-80: the Language and Its Implementation. Addison- Wesley, 1983.

[15] L. Jategaonkar and John C. Mitchell. ML with ex- tended pattern matching and subtypes. In Proc. of the ACM Conf. on Lisp and Functional Program- ming, 1988.

[16] Ralph Johnson and Justin Graver. A user’s guide to Typed Smalltalk. Technical Report UIUCDCS- R-88-1457, University of Illinois, 1988.

[17] Ralph Johnson, Justin Graver, and L. Zurawski. TS: An optimizing compiler for Smalltalk. In Proc. of ACM Conf. on Object-Oriented Programming, Systems, Languages and Applications, 1988.

[18] Bertrand Meyer. Object-oriented Software Con- struction. International Series in Computer Sci- ence. Prentice Hall, 1988.

[19] John C. Mitchell. Type inference and type contain- ment. In Semantics of Data Types, volume 173 of Lecture Notes in Computer Science, pages 257–278. Springer-Verlag, 1984.

[20] Dedier R´emy. Typechecking records and variants in a natural extension of ML. In Proc. of the ACM Symp. on Principles of Programming Languages, pages 77–88, 1989.

[21] J. C. Reynolds. User-defined types and procedural data structures as complementary approaches to data abstraction. In New Advances in Algorith- mic Languages, pages 157–168. Inst. de Recherche d’Informatique et d’Automatique, 1975.

[22] Michael B. Smyth and Gordon D. Plotkin. The category-theoretic solution of recursive domain equations. SIAM J. Comput., 11(4):761–783, 1982.

[23] A. Snyder. CommonObjects: An overview. SIG- Plan Notices, 21(10):19–28, 1986.

[24] Mitchell Wand. Complete type inference for simple objects. In Proc. IEEE Symposium on Logic in Computer Science, pages 37–44, 1987.

[25] Mitchell Wand. Type inference for record concate- nation and multiple inheritance. In Proc. IEEE Symposium on Logic in Computer Science, pages 92–97, 1989.