1 THE GAME
Here's a parlor game you can play at your next object-oriented party. The goal is to
intimidate as many people as you can into accepting your definitions.
The Playing Pieces are a set of statements (shown later on) containing the
words "type", "class", and "group". "Group"
is a wild-card word which can be replaced by either "type" or "class"
to generate one or more new statements. Your first goal is to generate all the statements
which are true about types and classes. That part is easy, of course, since you know all
the right answers. Your second goal is to achieve consensus with the other players,
getting all to agree on the same set of true statements. This part will also be easy,
assuming that everyone else knows the same set of right answers (hah!).
2 THE RULES
The game proceeds in the following stages:
- Read and argue about the rules.
- For each statement in the Playing Pieces, generate one or more statements by replacing
the word "group" with either "type" or "class".
Substitutions need not be consistent. Different substitutions may be used for different
occurrences of "group" in the same sentence.
- Make a list of all the generated statements which you know to be true.
- Compare lists with other players. Players having the same lists form coalitions.
- Coalitions then try to merge with other coalitions by persuading each other to change
their lists to arrive at a common set of statements.
Who wins? The largest coalition. When does the game end? It's hard to say. There's
another party going on next door, and there will be another one next week. You get to play
the game again and again, whether you like it or not.
What's the prize? For some people it's the challenge of the competition itself. Then
there's the gold mine of an inexhaustible topic of conversation. (No fair noticing that it
all gets repetitious after a while.) You also get the satisfaction of having participated
in a professional conference/workshop/meeting/committee. And there are bonus perks if you
were clever enough to get paid for having this party at some exotic location instead of
going to work.
You can also devise variations of the game. For instance:
- Invent more game pieces (statements about groups).
- Apply the statements to the published literature. For any particular document dealing
with types and/or classes, try to figure out:
- Which of our statements about types and classes are asserted to be true.
- Which statements seem to be implied or assumed.
- Which statements can't be so classified, because the document doesn't make clear what is
being assumed.
3 ORIGINS OF THE GAME
The concepts of "type" and "class" are fundamental to object
orientation, but the terms are used with a large variety of inconsistent meanings. It is
commonplace that an expert in the field "knows" the correct definitions, but
rare that several such experts agree. Many committees are trying to arrive at consensus
definitions, and there are many "authoritative" documents claiming to provide
the standard.
I was recently challenged to fulfill my claim that I could rattle off at least ten
different sets of definitions of these two terms. When I started to write them out, the
combinations and permutations of concepts q uickly got out of hand. So, like a good object
technologist, I decided instead to produce a set of reusable components that you can mix
and match to construct your own definitions. I chose to let you write this paper for me,
by providing you with a set of building blocks out of which you can make your own set of
definitions, or your own interpretation of what you think the experts' definitions are.
4 GAME EQUIPMENT
Like any game, we need some auxiliary equipment in addition to the main playing pieces.
In our case, we need definitions of other terms used in the statements about types,
classes, and groups.
Rule: you can't change the following definitions. These terms are themselves
controversial, so we try to introduce them in a relatively neutral form. Arguing about
them is a different game, and you lose points for getting sidetracked into such
discussions.
- The notions of operation, method, etc. are consolidated into the notion of
"function". A function
- has a name f,
- takes n parameters x1...xn,
- returns m results y1...ym (in the sense of a tuple), or a bag or set of such things.
A function could alternatively be defined as taking a single argument, possibly an
aggregate, and returning a single result, possible an aggregate. That doesn't materially
affect the game.
It doesn't matter if the function causes update, side effects, or state change.
- Several functions may have the same name. We specifically define the term
"function" to mean a specific function out of the set of functions having the
same name.
- One of the parameters is a distinguished parameter, sometimes also referred to
as a target. For convenience, we will assume this to be x1.
- For some functions and some specific argument values (actual parameters), invoking
f(x1...xn) causes a Violation Condition, returning no results.
- If there exists a sequence of specific argument values x1...xn such that f(x1...xn) does
not cause a Violation Condition, then f is applicable to each xi. (More
precisely, f is applicable to xi in the i-th role. This is significant when n>1.)
- For some functions and some specific argument values, invoking f(x1...xn) causes a Void
Condition, returning no results.
- The notion of a function implementation is captured in the notion of a
"script". A script defines the behavior of a function. There may be
several alternative scripts for a given function, each conforming to the external
specifications of the function. A script may specify an algorithm and/or a storage
structure in which function values are maintained.
5 PLAYING PIECES
We finally get to the real playing pieces, the statements about types, classes, and
groups. Remember, for each of these statements you can generate one or more statements by
replacing the word "group" with either "type" or "class".
Substitutions need not be consistent. Different substitutions may be used for different
occurrences of "group" in the same sentence.
Once in a while a suggested substitution will be offered in brackets, corresponding to
a fairly common usage. Feel free to use this or the opposite substitution.
- There is a binary predicate which we shall call Belongs such that for any
object x and group g, the predicate Belongs(x,g) is true or false.
- Belongs(x,g) is true if and only if x is an instance of the group g.
- An object can belong to more than one group.
- For a group g, the truth of Belongs(x,g) can change during the lifetime of x.
- Types apply to literals (data values), while classes apply to non-literal objects. Thus
if Belongs(x,g) holds for a literal x, then g is a type; if it holds for a non-literal x,
then g is a class.
- An alternative statement is obtained by swapping "class" and "type".
- Types classify objects by their intrinsic, immutable nature. Classes represent mutable
characteristics of objects, sometimes thought of as the roles an object might
play. Thus, the truth of Belongs(x,g) can change during the lifetime of x if g is a class,
but not if g is a type.
- An alternative statement is obtained by swapping "class" and "type".
- Types classify objects by their (data) structures, while classes classify objects by
their behavior (semantics).
- An alternative statement is obtained by swapping "class" and "type".
- A class has a finite set of things belonging to it, while a type may be infinite in
extent.
- A function f taking n arguments has an associated sequence of n argument groups
g1...gn such that f(x1...xn) causes a Violation Condition if Belongs(xi,gi) is false for
any i.
- There is a distinguished argument group g1 called the target group
for f.
- No two functions may have the same name and the same associated sequence of argument groups
g1...gn.
- No two functions may have the same name and the same target group g1.
- A function f returning m results has an associated sequence of m result groups
g1...gm such that Belongs(yi,gi) is true for each yi in any result returned by f.
- The signature of a function f consists of
- its argument groups g1...gn.
- its target argument group g1.
- its non-target argument groups g2...gn.
- its argument groups g1...gn and its result groups.
- its target argument group g1 and its result groups.
- its non-target argument groups g2...gn and its result groups.
- its name and its argument groups g1...gn.
- its name and its target argument group g1.
- its name and its non-target argument groups g2...gn.
- its name and its argument groups g1...gn and its result groups.
- its name and its target argument group g1 and its result groups.
- its name and its non-target argument groups g2...gn and its result groups.
- The group interface of a group g consists of
- a set of specific functions.
- a set of function names.
(See statement 30.)
- The group interface of a group g includes
- the functions for which g is the target group.
- the functions for which g occurs as an argument group.
- the functions for which g occurs as an argument or result group.
- A set of pairs <f,i> such that g occurs as the i-th argument group for
function f.
- A similar construct including both argument groups and result groups.
We will say that a group g holds a function f, i.e., Holds(g,f),
whenever the function f is in the group interface of group g.
- A function can be held by more than one group, e.g., by all of its argument groups.
- Two groups can have the same group interface. (E.g., the groups
People and Wines can each have a group interface consisting of functions named Name
and Age.)
- The group interface of a group can change without changing the identity of
the group.
- A group [class?] gc contains a set of scripts providing implementations for a set
of functions. The data structures associated with the scripts may be called the template
for the group [class].
- The functions implemented by the scripts of the group [class?] gc must have
distinct names.
- The functions implemented by the scripts of the group [class?] gc constitute the group
interface of an associated group [type?] gt. It is then said that the group
[class?] gc implements the group [type?] gt.
- Several groups [classes?] can implement the same group [type?].
- If an object belongs to a group [type?], then it belongs to exactly one of the groups
[classes?] which implement it.
- The set of scripts associated with the group [class?] gc can change without
changing the identity of gc.
- Every group [type?] g0 has a corresponding group [class?] g1 such that g0
has a group interface but g1 does not, while Belongs(x,g1) is meaningful but
Belongs(x,g0) is not. [I.e., types have interfaces, classes have instances.]
- A group [type?] g0 may have several corresponding groups [classes?] gi
such that Belongs(x,gi)=> Belongs(x,g0). [I.e., a class contains some subset of the
instances of an associated type.]
- There is a subgroup relationship among groups such that Subgroup(g1,g2)
& Belongs(x,g1) => Belongs(x,g2).
- There is a subgroup relationship among groups such that Subgroup(g1,g2)
& Holds(g2,f) => Holds(g1,f).
- There is a subgroup relationship among groups such that Subgroup(g1,g2)
& Holds(g2,f1) => Holds(g1,f2), where f1 and f2 have the same name; they may or may
not be the same specific function. (This relates to statement 15.)
- If every function held by group g1 is held by group g2, then Subgroup(g1,g2).
E.g., if the group interface of group g consists of the Name function, then
g is a subgroup of any group whose group interface includes a Name
function.
- If an object x satisfies the group interface of group g, then Belongs(x,g)
necessarily follows. [Need to develop a definition of "satisfies"; depends a lot
on statement 16.] E.g., if x can be edited and printed, then it must be a document.
- Belongs(x,g) may be asserted, or it may be the consequence of subgroup
relationships. It then necessarily follows that x satisfies the group interface of group
g. E.g., if x is made a document, then it follows that x can be edited and printed.
- A group is an object.
- A group is created by an explicit operation.
- A group can be constructed by invocation of a (parameterized) constructor
operation.