Class-is-type is inadequate for object reuse.
It is well known that class and type are two different concepts in object-oriented programming languages (OOPLs). However, in many popular OOPLs, classes are used as types. In this paper, we argue that the class-is-type principle is a major obstacle to software reuse, especially to object reuse. The concepts of the basic entities, i.e., objects, object classes, object types, and object kinds, in the type hierarchy of OOPLs are revisited. The notion of object reuse is defined and elaborated. In addition, we show that parameterized types and generic functions are better served by used kind-bounded quantification than universal quantification and other mechanisms.
Introduction
Object-oriented languages and technology have propelled software reuse to an unprecedented level. However,
software reuse at the current stage is still mostly (1) within a single software project and (2) in the form
of source-code reuse and as libraries. The dream that software construction would be similar to assembling
Integrated Circuits (ICs) in hardware is still not realized. Programming in many essential aspects is the same as
twenty years ago. Software construction is still basically at the stage of program writing, and has not advanced
to the stage of software integration (SI).
We consider that object reuse (rather than class reuse) is a key concept in software integration. Objects
are the basic building blocks of an object-oriented system. They are first-class citizens. Programming via
software integration means that we can reuse and integrate objects, which are developed independently (by other
This work is supported by the Natural Sciences and Engineering Research Council of Canada grant OGP0041630.
projects or object vendors) and in an executable form, into our program conveniently without knowing their
implementation details.
We consider that object reuse is a much more important concept than class reuse in software integration.
Consider an example in the physical world: When we purchase an air-conditioner for a house, we do not need or
want to know the design and technical details of the air-conditioner. It is only necessary for us to know whether
the air-conditioner satisfies a few specifications, e.g., cooling capacity, physical dimensions, and voltage. In this
case, the object (the air-conditioner) and its type (a few specifications) are our concern and interest. We do not
need or even want to know the class of the object (the technical details of the air-conditioner).
We consider that one major cause of the stagnation in reuse is that, in most major (class-based) object-oriented
programming languages, object classes are directly used as object types. For example, when we specify
the object type of a function parameter, we use a class in place of a type. This approach may be due to the
fact that the semantics of an object type is easy to define by a specific implementation. It is important to
notice that classes are implementation-dependent entities in general and also objects cannot exist autonomously
apart from their class definitions in current class-based languages. In contrast, object types are implementation-independent
entities. The class-is-type principle used in many object-oriented languages restricts an object type
to a specific implementation. We argue in this paper that the class-is-type principle, not the classes themselves,
is an obstacle to object reuse.
Another issue that concerns the type hierachy of object-oriented languages is about parameterized types.
Note that a C++ class template is a parameterized type under the class-is-type principle. We consider that a
parameterized type is just a type function which maps a given type (or types) to a type. The domain of such a
type function, i.e., the domain of its type parameter(s), is commonly represented by T (T n ), where T is the set
of all types. However, in many cases, not all types can be used to replace the type parameter of a parameterized
type. There are restrictions which are implicitly imposed by the parameterized type definition. We consider
that object kinds, which are higher-level entities than object types [31, 32, 26, 25, 34], are best suited for defining
the domains of type parameters of parameterized types as well as for those of generic functions.
Objects, object classes, object types and object kinds are basic entities in the type hierarchies of various
object-oriented languages [31]. In the next section, we review the basic concepts of those entities as well as the
relationships among them. We also discuss the similarities and differences between abstract classes, interfaces,
and object types. We focus our attention to the class-is-type principle, giving an initial analysis on its advantages
as well as its potential problems. We also distinguish object kinds from supertypes.
Object reuse is defined and analyzed in Section 3. We consider that object reuse concerns mainly the
following five issues: (1) object creation, (2) object autonomy, (3) object application, (4) object integration,
and (5) object modification. We describe each of the five issues as well as its role in object reuse.
In Section 4, we discuss what roles classes and the class-is-type principle play in each of the five issues of
object reuse. We find that while classes can be apt at object creation and object autonomy, the class-is-type
principle is inadequate for object application, object integration, and object modification, i.e., all the last three
issues of object reuse. We also give our insight analysis on why this is the case.
In Section 5, we argue that parameterized types and generic functions can be best served by kind-bounded
qualification, i.e., each type parameter is qualified by a higher-level entity "object kind".
We conclude our paper in Section 6 by summarizing our suggestions on the further development of object-oriented
languages.
Type hierarchy of object-oriented systems
In this section, we give our view on the basic type entities in object-oriented systems. We will consider objects,
object classes, object types, as well as the concept of object kinds. We will be brief on the commonly accepted
concepts and pay more attention on the points that are related to the topics of the subsequent sections of
the paper. Note that object classes and object types are very different entities; however, the approach that
object classes are used in place of object types, i.e., the class-is-type principle, is used in many object-oriented
languages, including C++ and Java. We will also describe the concept of object kind and the fundamental
differences between supertypes and object kinds. The three seemingly equivalent terms, abstract class, interface,
and object type, are also compared.
2.1 Objects
An object is an integrated unit of data and methods, which is an abstraction of an application domain or an
implementation domain entity, which has crisp boundaries and meaning for the problem concerned.
Each object has an identity, data fields, and method fields. The data fields store the internal state of the
object and act as data storage, while the method fields are functions that modify the internal state of the object,
access the data storage, and interface the object with the outside world.
The internal state of an object is modified dynamically during execution. Normally, this change can be made
only through its own methods. Not all methods may be accessed from the outside of the object. Some may only
be used by other methods of the object. We call those methods that can be directly accessed from the outside
the properties of the object.
Clearly, objects are first-class entities of object-oriented systems.
2.2 Object classes
serve as the descriptions of objects as well as a mechanism to create objects. Objects are instances
of classes. In class-based languages, the only way to describe an object is through its class. A class is also
considered a set of objects which share the same description. Thus, the relation between an object O and its
class C can be denoted O 2 C.
In general, object classes are implementation-dependent entities. For example, a stack class with an array
implementation and a stack class with a linked-list implementation are considered as different classes. Different
objects of the same class have the same implementation, but different identities and maybe different internal
states.
An abstract class may be independent of any implementation. However, an abstract class cannot be the
description of an object directly. An object can only be instantiated directly from a concrete class but not from
an abstract class. So, an abstract class as a set has no direct object members.
Object classes are static entities. Unlike objects, classes cannot be changed at runtime once they are defined.
The relationship between classes are static, too. We can modify the relationship between objects but not their
classes at runtime.
We call a property of a class is a method of the class that can be accessed directly from the outside. All
objects of a class (direct members) share exactly the same set of methods and, thus, they have exactly the same
properties.
2.3 Object types
Intuitively speaking, an object type is a description of a collection of properties without giving any implemen-
tation. Thus, an object type is also considered a set of objects that have the same properties, but possibly
different implementations. Clearly, object types are implementation independent entities. All objects of the
same class are also of the same object type. However, all objects of the same object type may not belong to
the same class. For example, two integer-stack classes S 1 and S 2 are implemented with a linked list and an
array, respectively. They have the same set of operations: push(int), pop(), top(), empty(). S 1 and S 2 are two
different classes, but of the same type, say T S . In this case, we also say that
is an implementation of T S .
A stack object O S of type T S is considered a member of the set T S , denoted
O
The fact that S 1
An object type may be defined in many ways. For example, an object type can be define by listing all its
properties (the names and signatures of all its methods) [18], by extracting a type from a class using an operator
[1], or by implicitly deleting the implementation details of a class when a type is needed. Similar to classes,
subtypes can be defined in terms of their supertypes.
We say that an object O is of type T if O possesses the properties of T . Note that O can be of type T in
spite of that the creation of O may be independent of the definition of T .
In some cases, an object O actually possesses the properties of an object type T , but O and T use different
names for their properties. For example, O has the two properties below:
void insert-top( Content );
Content delete-top();
and T is defined as:
Type T -
Content pop();
void push( Content );
and we know that insert top is the same property as push and delete top corresponds to pop. Then it would
be convenient to have a "is of " language construct like the following:
Object O is-of Type T -
insert-top() is push();
delete-top() is pop();
which allows the programmer to claim that O is an object of type T and to specify the correspondence between
the properties of O and those of T . Type checking and type equivalence are usually quite complex. The above
construct would be helpful in reducing the work of the compiler.
More formally, the "is of " is a binary operator which links an object to an object type. The "is" operator
inside the "is of " construct is a propterty matching operator, which links a property of the object to a property
of the object type. A simple interpretaion of the "is of " construct is that we require the two properties on the
both side of the "is" operator to have exactly the same signature although they may have different names. This
interpretaion is in general good enough for practical purposes. A more flexible and complex interpretaion is to
require that the object type of the property on the lefthand side, which may be a function type, is a subtype
of that of the property on the righthand side. This interpretation would involve contravariance and covariance
rules.
The relationship between classes and object types is an interesting one. They are both collections or sets of
objects. But, object types are implementation independent entities while classes are not.
We say that an object type defines a set of objects that have the same external behaviors. However, the
precise meaning of behaviors would become extremely complicated to define if the behaviors were not restricted
to a specific implementation. We may use, e.g., axiomatic, denotational, or logical way to specify the behaviors
of an object type, but all those methods are too complex to be practical at the moment. The easiest way to
precisely define the semantics of the properties of a type is, perhaps, to give a specific implementation of the
operations. In other words, it is easy and safe to define an object type by an object class. This comes what we
see in many popular object-oriented languages the class-is-type principle: using object classes as object types.
The main advantage of using the class-is-type principle is that object types defined this way are rigorous,
unambiguous, precise, and easy to define, although not necessarily easy to comprehend. The main disadvantage
is that each object type is restricted to only one particular implementation and, thus, becomes implementation-
dependent. We will argue later that this is a major obstacle to object reuse and software integration.
In some object-oriented languages, e.g., Theta [18], object types are separate entities from classes. In Theta,
a new object type, or simply a new type, is defined by the names and the signatures of its methods (properties).
The semantics of the methods (properties) is not formally defined and is left for the programmer to interpret
from their names and possibly informal definitions in the comments. For example, a stack type and its operations
push, pop, top, etc. are well understood simply from their names. A graph type can be easily understood with a
few lines of explanations in the comments. This informal approach can be dangerous if without care. However,
this is perhaps the only practical way of defining an object type in a program without restricted it to a specific
implementation, and this way works well in the physical world.
Abstract classes are available in many major object-oriented languages. Abstract classes can play the role
of object types in certain extent. However, abstract classes are not object types. The main differences between
an abstract class and an object type are the following:
(1) Abstract classes may or may not be implementation independent while object types are implementation
independent with no exception. There is no consistency in this aspect on abstract classes.
(2) For an object O and an abstract class C, we say that O 2 C if there exists a concrete class C 0 that is a
descendant of C such that O is an instance of C 0 . In other words, there has to exist a declaration link or
family relation between O and C, that is, we have to declare that C 1 is a subclass of
subclass of C n , and O is an instance of C 0 . In contrast, the fact that O is of type T can be simply implied
by the fact that O has all the properties of T . The relationship can be direct. There does not necessarily
exist a family relation here.
Interfaces in Java are one-step closer to object types than abstract classes are. Interfaces are implementation-independent
entities. Thus, the above (1) does not apply on them, but (2) still does.
2.4 Object kinds
All object types that share a certain set of common properties form an object kind and it is specified by those
properties. Hence, object kinds are at a higher-level than object types. The members of an object kind, if any,
are object types. Object kinds have been introduced and studied in [31, 32, 26, 25, 34]. The name kind has also
appeared in [16, 21, 8, 9, 10], however, the connotations of this word are not the same. We will show later in
Section 5 that object kinds are useful in defining parameterized types and generic functions.
The relation between an object kind and its members, i.e., object types, cannot be represented as a super-type
relation. Consider two object types: word (or character string) and acyclic graph, where a word can be
implemented by an array or a linked list and an acyclic graph by an adjacency matrix or an adjacency list, etc.
Here, we name them type W and type G, respectively. These two different types have a common property: the
distance between two words, respectively two acyclic graphs, can be measured, i.e., each of the two object types
has a distance function. Naturally, we can represent the set of types that have a set of common properties by a
higher-level entity. In this case, we define an object kind K to be a set of all types that have a distance function.
Clearly, both W and G are types in K. It is important to notice that K is not a supertype of W and G, and K
cannot be replaced by a supertype of W and G in this case. Assume that we define a supertype T (instead of a
kind K) such that T has a distance function which measures the distance between each pair of objects of type
T . This would imply that there is a distance function between a word and an acyclic graph by the subtyping
principle. This is clearly not what we intend to define.
3 Object reuse
In this section, we consider the issues that concern object reuse.
We classify objects into the following two categories: internal objects and external objects. In a program,
we call the objects created within the program internal objects and those created elsewhere but used in the
program external objects. Since the reuse of internal objects is relatively straightforward and involved in fewer
issues than that of external objects, our discussion is focused on the reuse of external objects. The sources of
the external objects may include other projects and object vendors.
Object reuse is different from class reuse or source code reuse. By object reuse, we mean that we reuse
objects that are already created and in an executable form, especially those that are developed independently,
in a larger programming environment.
Object reuse may involve the following five interrelated issues:
(1) object creation: how an object is created,
(2) object autonomy: whether an object can survive autonomously,
(3) object application: how an object is used,
object integration: how two or more objects are integrated into larger objects,
object modification: whether an individual object can modified and what are the side effects.
An object has to be created first before any application. Object can be created in many ways. In class-based
languages like C++ [28], Java [3], Eiffle [22], and Modula-3 [23], objects are instantiated from classes. In
object-based languages, e.g., Cecil [11], Self [30], and Omega [6], objects are created by cloning and extension of
prototypical objects without the existence of classes. Apparently, how an object is created does not necessarily
affect how an object is used internally or externally. We consider that object creation is not an essential issue
for object reuse.
In order for an object to be used not only internally but also externally in terms of the environment where
it is created, it is essential that the object should be able to survive autonomously. This means that the object
is executable without its class or other objects of its creation environment. Many issues may involve object
autonomy, which include embedding versus delegation, global variables and class variables, and visibility of
attributes. However, we feel that it is not difficult for any object-oriented languages to be modified to safely
export objects, which can live autonomously and be reused safely in other runtime environments. For example,
objects that are going to be exported can be specially marked as "exporting" objects, and the compiler will check
whether they satisfy certain conditions for autonomy, e.g., no global variables, and if they do, then generate the
autonomous objects using embedding instead of delegation, etc.
Object application by definition is clearly the most important issue in object reuse. What conditions are
necessary for an external object to be used in (or linked to) a programming environment? Let us again consider
the air-conditioner example. When we purchase an air-conditioner for a house, it is necessary for us to know
whether the air-conditioner satisfies a few specifications, e.g., cooling capacity, physical dimensions, and voltage.
However, we do not need or want to know the design and technical details of the air-conditioner. Also, any
air-conditioner that satisfies our requirements, whatever its internal implementation is, would do the job. The
internal implementation is not part of our requirement. In this case, what we need are the object and its object
type, and whether the object type conforms the required object type, and we do not need and want to know
the object class. Thus, an object type system which is separate from the class system need to set up for object
reuse. In this type system, for example, an object type may be explicitly declared, or obtained by using an
operator which, given a class C, removes all the implementation details of C and returns an
object type. Object types may have their own inheritance hierarchies. Most importantly, the system should be
able to check, for a given object and a given object type, whether the object is of the give object type.
When an external object is used in a programming environment, it may not just act as a server providing
one-way services, it may also call the methods of (or send messages to) some internal objects. In other words,
the object may interact with internal objects. Also consider the situation when we use two or more external
objects in our programming environment. Those objects may require to interact with each other. In a strong-
typed object-oriented system (as we have assumed), each object involved in a multi-object interaction needs to
know the type information of the other objects. However, we may be at a situation that external objects are
developed independently by different vendors. Thus, in general, the developer of each object does not know how
the types of other objects are defined. There are many different ways to solve this problem. Example solutions
are (1) standardization of object types for object interfaces, (2) writing wrapper or adapter programs in order
for independently developed objects to interact, and (3) using the "is of " construct suggested in Section 2 to
match the equivalent types that have different appearances.
Solution (1) above may be a long-term solution. However, even in the long term, it is difficult to standardize
all the types for reusable objects. Other mechanisms have to be in place. The wrapper and adapter programs
are complicated and the programmer has to know the type declarations of each object involved (and have to
have their class declarations under the current class-is-type principle). It would be much more convenient to
use the "is of " construct together with the standardization.
It would also be convenient if objects can be modified after creation. In several object-based languages,
both data fields and methods of an object can be modified in a uniform way without any side-effect. Object
modification and object autonomy are two closely related issues. However, we consider this issue as a convenience
issue.
The notion of object reuse appears to be similar to that of component-based computing [29] in many ways.
Both a component and an object (in object reuse) are being independently developed and in an executable form.
We consider that a component is just an object or a collection of closely related objects in our term. However,
component-based computing mechanisms in general are not part of an object-oriented language; they impose
an external structure on the programs written in current programming languages rather than change them.
IDL can be consider a standard way to specify object types. In some sense, the component-based computing
mechanisms are meant to alleviate the problems of current object-oriented languages in object reuse from the
outside rather than from the inside.
4 Class-is-type is inadequate for object reuse
play two major roles in class-based languages: (1) as an object description and creation mechanism,
and (2) as object types.
As an object creation mechanism, classes can serve the first two issues of object reuse well. With some minor
modifications, the current popular class-based languages can be used to develop autonomous objects. Objects
can be also created in many other ways in object-based [1] or prototype-based languages [27, 24, 13], e.g., by
direct declaration and by cloning and extension from prototypical objects. We consider that classes as an object
creation mechanism is as adequate as any other mechanism whether it is for creating a single object or a stock
of objects.
We now consider the class-is-type principle, i.e., classes plying the role of object types, in relation to object
reuse.
Let us assume that we are going to use a "registrar" object, from an external source, in our program. In
our program, we instantiate many student objects from the "STUDENT" class (type) in our program, each of
which has a method for registration. When a STUDENT s1 registers, it calls the registration method and uses
the external object registrar for registration:
s1:register( registrar );
This implies that we have the following definition of a method for registration in STUDENT class:
Boolean register( REGISTRAR );
where REGISTRAR is the class, as well as the object type, of registrar. The class REGISTRAR has to be
declared in our program. Since the class-is-type principle is used, we have the following problems:
ffl The class REGISTRAR (and possibly its descendants), which describes all the implementation details
of the object registrar, can be very complicated and large (this is why we reuse it instead of developing
it by ourselves). Since we have to include the class REGISTRAR (and its descendants) in our program,
it would be more economical just to instantiate a registrar object in our program rather than to use the
external object registrar. Then object reuse degenerates into class reuse (or source code reuse).
ffl If both registrar and student s1 are external objects and are created independently, then the register
method of the s1 object may not be defined as above since the student object does not have the class
definition of a registrar when it is created. (Also, the registrar object does know the class definition of s1
objects.) This seriously restricts the way the registrar and s1 objects are defined and makes integration
of those objects extremely complex.
ffl Neither the registrar object nor the s1 object can be modified to have additional features or more efficient
implementations once it is created.
From the above example, we can observe that there are the following three general problems of the class-is-
type principle for object reuse:
(1) Classes are implementation dependent entities. The class-is-type principle unnecessarily restricts an object
type to a specific implementation. It is not compatible with the general idea of reuse.
(2) Under the class-is-type principle, an object O can be used where object type (class) T is specified if O is
an instance of T or an instance of a descendant class of T . In other words, O has to have a declaration
link or a family relation with T . Since external objects are developed (programmed) independently, this
necessary link makes the reuse of external objects complicated and difficult.
(3) Classes are detailed description of objects. When the information about the type of an object is re-
quired, the class-is-type principle makes the object type information too cumbersome and even sometime
redundant to the object itself.
The class-is-type principle makes the realization of object application, object integration, and object modification
difficult and even impossible in some cases.
5 Parameterized types and generic functions
parameterized type is a function which maps a type (or several types) into another type. Let T denote the
set of all types. Then a parameterized type P is a function
For example, a C++ Sorted Vector template declaration [28] is in the following:
template!class T? class Sorted-Vector -
T* v;
int sz; // size of the vector
int n; // current number of elements
public:
explicit Vector( int );
T& operator[](int i);
if (n == zs) return false;
for (int
return true;
bool delete( int i ); // delete ith element
where T in the above is the type parameter of the template. The template maps the int type to an integer
Sorted Vector type, maps the char type to the character Sorted Vector type, etc. It appears that given any type
the template would map it to a Sorted Vector of that type. However, this is not totally true. Notice
that there is a comparison v[i] ! a between two objects of type T in the function insert. This implies that T
cannot be any type but only types that have a '!' operator. So, the domain of this type function (the template)
is not T (the set of all types) but a subset of T . We call this subset a KIND K. Then the Sorted Vector
template is a type function: K ! T . (In general, a parameterized type is a function: K 1
are KINDs.) The KIND K may be defined as follows:
KIND K: for T in K -
bool operator! (T, T);
Then the template may be written as follows:
template!K T? class Sorted-Vector -
where !K T? denotes that type T is bound to KIND K.
Similarly, a generic function is a function that maps from a type to a function and, thus, kinds can be used to
define the domain of such type functions, too. We call such type of polymorphism KIND-bounded polymorphism.
Note that we have discussed in Section 2 that KINDs cannot be replaced by supertypes. KIND and supertype
are clearly two different concepts.
Consider this situation: a type T has a comparison operator, which is essentially the same as ! but uses
a different name, say "less than". A language construct like the following to explicitly link the corresponding
names may be introduced:
Type T is-in KIND K -
less-than is operator!;
By using KIND-bounded polymorphism, there are at least the following advantages:
(1) The restrictions, on type variables, that are implicitly imposed by the definition of a parameterized type
or a generic function are explicitly and clearly stated by the definition of a KIND. The user of the
parameterized type or generic function need not read the detailed definition of the parameterized type or
generic function to find out all the buried constraints.
(2) KINDs are at a higher level than types. A KIND does not affiliate to a specific parameterized type or
a generic function. KINDs are natural entities to represent constraints on types, which make generic
constructs conceptually more transparent.
Notions similar to kinds have been studied in [16, 21, 20, 8, 9, 10]. The where clause of parameterized
procedures and parameterized types in CLU [19] and Theta [18], as well as the with statement of generic
procedures in Ada [2] are all similar to the definition of KINDs. However, unlike kinds, the where clause and the
with statement are not independent entities. They are an inseparable part of a specific parameterized type etc.
In contrast, kinds are treated uniformly as other entities in our type hierarchy. Several parameterized types and
genric functions that have the same restrictions on their type parameters can be expressed by the same KIND.
Comparisons between KIND and opaque types in Modula-3, signatures in G++ [5], "kinds" in Quest [10], etc.
can be found in [31].
The concept of object kinds has shown to be useful in realizing algorithmic abstraction [31] in programming
languages. We conjecture that object kinds will also be useful in formal or semi-formal descriptions of design
patterns as well as in their implementation in object-oriented languages.
6 Conclusion
In the past half century, programming languages have been continuously evolving to higher levels. There exist
two opposite directions of the development: programming languages are getting more and more complicated
conceptually, but easier and easier technically. It takes a much longer time to learn a programming language
now than forty years ago, but programming for the same task takes much less time.
In this paper, we have made several suggestions to the development of object-oriented programming lan-
guages, which are summarized in the following:
1. Separation of object types from object classes.
2. Exporting autonomous objects with their type information.
3. Introducing a type-matching construct like the "is of " construct in Section 2, which matches the type of
a given object to a given object type.
4. Introducing object kinds, kind-bounded polymorphism, and the "is in" construct for fitting a object type
into an object kind.
An object type system that is separated from classes would be much more complicated to implement.
However, the system would make an object-oriented language much more flexible and feasible for object reuse
and software integration.



--R

A Theory of Objects
Ada 9X mapping/Revision Team
The Java Programming Language
Programming in Ada

"Type-Safe OOP with Prototypes: The Concept of Omega"
Algebraic Specification Techniques in Object Oriented Programming Environments
"A Modest Model of Records, Inheritance, and Bounded Quantification"
"The Semantics of Second-order Lambda Calculus"
Formal Description of Programming Concepts - IFIP State-of-art Report
"The Cecil Language Specification and Rationale"
"F-Bounded Polymorphism for Object-Oriented Programming"
The Interpretation of Object-Oriented Programming Languages
Data Types Are Values
Principles of OBJ2
Interpretation Fonctionelle et 'elimination des coupures de l'arithm'etique d'ordre sup'erieur
The Algebraic Specification of Abstract Data Types
Theta Reference Manual - Preliminary Version
Abstraction and Specification in Program Development
A Semantic Model of Types For applicative Languages
An Investigation of a Programming Language with a Polymorphic Type Structure
Eiffle: The Language
Systems Programming with Modula-3

Introducing KINDS to C

"A shared view of sharing: The treaty of Orlando"

Component Software - Beyond Object-Oriented Programming
"Self: The Power of Simplicity"
"Algorithmic Abstraction in Object-Oriented Languages"
"Software Reuse via Algorithm Abstraction"
On Parametric Polymorphism in Object-Oriented Languages
Algorithm Abstraction via Polymorphism In Object-Oriented Languages
--TR
Data types are values
Abstraction and specification in program development
A shared view of sharing: the treaty of Orlando
The semantics of second-order lambda calculus
A modest model of records, inheritance, and unbounded quantification
Inheritance is not subtyping
F-bounded polymorphism for object-oriented programming
Systems programming with Modula-3
Eiffel: the language
Component software
Principles of OBJ2
The C++ Programming Language
The Integration of Object-Oriented Programming Languages
Programming ADA
A Theory of Objects
A semantic model of types for applicative languages
An investigation of a programming language with a polymorphic type structure.
Algorithmic abstraction via polymorphism in object-oriented programming languages

--CTR
Chitra Babu , D. Janakiram, Method driven model: a unified model for an object composition language, ACM SIGPLAN Notices, v.39 n.8, August 2004
kinds;object reuse;classes;kind-bounded polymorphism;parameterized types;generic functions;types;objects;class-is-type principle