<<

Subtyping is not a go o d \Match" for

?

ob ject-oriented languages

1 1 ?? 2

Kim B. Bruce ,LeafPetersen , and Adrian Fiech

1

Williams College, Williamstown, MA, USA

2

Memorial University of Newfoundland, St. John's, Newfoundland, Canada

Abstract. Wepresent the design and rationale of a new statically-typ ed

ob ject-oriented language, LO O M. LOOM retains most of the features

of the earlier language PolyTOIL. However the relation is

dropp ed from LOOM in favor of the matching relation. \Hash typ es",

which are de ned in terms of matching, are intro duced to provide some of

the b ene ts of subtyping. These typ es can b e used to provide supp ort for

heterogeneous data stuctures in LOOM. LO O M is considerably sim-

pler than PolyTOIL,yet is just as expressive. The typ e system for the

language is decidable and provably typ e safe. The addition of mo dules to

the language provides b etter control over information hiding and allows

the provision of access like that of C++'s friends.

1 Intro duction

Most statically-typ ed ob ject-oriented programming languages, including C++

+

[ES90], Java [AG96], Ob ject Pascal [Tes85], and Mo dula 3 [CDG 88], su er

from very rigid typ e systems whichcanblock the easy expression of program-

mers' ideas, particularly in the de nition of sub classes. Other statically-typ ed

ob ject-oriented languages, such as Ei el [Mey92] and Beta [MMMP90], are more

exible, but require run-time or link-time checks in order to eliminate holes in

the typ e system. One imp ortantgoalof our previous work in designing static

typ e systems for ob ject-oriented languages has b een to design exible, yet safe,

static typ e systems (see for example [Bru93, Bru94, BSvG95]). In this pap er we

prop ose a fairly radical departure from previous statically-typ ed ob ject-oriented

languages by dropping subtyping in favor of a relation called matching and a

new typ e constructor related to matching.

It has b ecome clear in the last several years that the concepts of inheritance

and subtyping in ob ject-oriented languages are not at all the same. (See [Sny86]

for early hints, and [CHC90, AvdL90, LP91] for more de nitive treatments of the

topic.) In earlier pap ers [Bru93,Bru94, BSvG95], weintro duced the notion of

matching, a relation b etween ob ject typ es which is more general than subtyping.

?

Bruce and Petersen's researchwas partially supp orted by NSF grant CCR-9424123.

Fiech's researchwas partially supp orted by NSERCgrant OGP0170497.

??

Current address: Scho ol of Computer Science, Carnegie-Mellon University, Pitts-

burgh, PA, USA

A history of matching can b e found in [BSvG95]. See also [AC95] for a discussion

of explanations of matching in terms of F-b ounded and higher-order subtyping.

An imp ortant feature of matching is that if two classes are sub classes, then

the corresp onding ob ject typ es are in the matching relation. However, these

typ es are not generally in the subtyp e relation if the language includes a typ e

expression, MyType, standing for the typ e of self. Since MyType is extremely

valuable, we end up with a mismatchbetween subtyping and inheritance.

The language PolyTOIL [BSvG95] supp orts b oth subtyping and matching. It

also supp orts b ounded p olymorphism where the b ounds on typ e parameters are

given in terms of the matching relation. Unfortunately, the relations of matching

and subtyping are similar enough that it might b e dicult for a programmer to

keep their di erences straight. As a result we b egan considering the p ossibility

of simplifying the language by dropping one or the other.

It was clear that matching was absolutely necessary in PolyTOIL in order to

express the typ e-checking rules for sub classes, as well as to provide constraints

for p olymorphic op erations and data structures. Subtyping was to o restrictive

to serve either of these purp oses. Moreover, as welooked at the sample programs

we had written in PolyTOIL, we noticed that we rarely used subtyping. In the

presence of MyType and match-b ounded p olymorphism, we almost never needed

to explicitly change the typ es of metho ds in sub classes.

With this in mind, we decided to be bold and investigate the results of

eliminating subtyping in favor of matching. While this caused no problems with

the inheritance mechanism, we did discover a few situations where we found

it dicult to do without subtyping. To deal with this we intro duced a new

typ e constructor, #T ,which represents elements whose typ es matchthetyp e T.

With this addition, we found that we had a language whichwas essentially as

expressiveas PolyTOIL ,yet signi cantly less complex.

In the next section we review brie y the main features of PolyTOIL . In

section 3 we intro duce the language LOOM. We pay sp ecial attention to the

intro duction of a new typ e constructor which can b e applied to ob ject typ es to

form typ es whichhave prop erties similar to subtyp es (but are less restrictive).

In the following section weprovide a brief overview of the technical results used

to justify the use of the language: typ e-checking is decidable and the language

is provably typ e-safe. Weprovide a brief overview of LO O M 's mo dule system

in section 5. Finally in section 6 we summarize and evaluate the features of the

language.

2 Intro duction to PolyTOIL and Matching

In [BSvG95]weintro duced PolyTOIL , a statically-typ ed ob ject-oriented pro-

gramming language which provides all of the usual constructs of class-based

ob ject-oriented languages. In particular, it supp orts ob jects which consist of

instance variables and metho ds, and in which computation is based on message-

sending. Reuse is supp orted via inheritance, subtyping, and a form of b ounded p olymorphism.

We refer the reader to [BSvG95] for the details of the language. Weprovide

only a brief summary here. Relatively innovative features of the language include:

{ The use of MyType in classes to refer to the typ e of self, the receiver of the

message.

{ The treatment of classes as rst-class values of the language. They have

typ es and can b e b oth parameters to functions and returned as the results

of functions.

{ The separation of the inheritance and subtyping , in order to avoid

problems which can arise with so-called binary metho ds.

{ The intro duction of a new ordering called \matching", written <# , which

corresp onds closely to typ e changes allowed in de ning sub classes. Subtyp-

ing, written <: , is also supp orted.

{ Supp ort for a form of b ounded p olymorphism, called match-bounded poly-

morphism in which the b ound is expressed in terms of the new matching

ordering.

Within the scop e of each ob ject (or class), PolyTOIL de nes a typ e identi er

MyType that represents the typ e of the ob ject itself. This typ e is \anchored" to

the typ e of the ob ject in which it app ears, so that an app earance of MyType

in the typ e of a metho d inherited from another class represents the typ e of an

instance of the current class, rather than the parent class in which the metho d

was de ned.

Matching is a relation b etween typ es whichisvery similar to subtyping, but is

designed to corresp ond b etter to the inheritance of classes and ob jects.

An ob ject typ e  matches an ob ject typ e  in PolyTOIL , if for every metho d

m :  included in ob ject typ e  there is a corresp onding metho d m :  included

i i i i

in ob ject typ e  suchthat <:  (where o ccurrences of the keyword MyType

i i

in the metho d typ es are treated as uninterpreted free variables).

The de nition of subtyping for ob ject typ es is similar to that for match-

3

ing, but also requires that MyType only o ccur p ositively in metho d typ es (see

[BSvG95] for de nitions and details). In particular, an ob ject typ e with a metho d

with parameter of typ e MyType cannot haveany non-trivial subtyp es. As a re-

sult, if a class has a metho d with a parameter of typ e MyType, then sub classes

will not giverisetosubtyp es.

While <:  implies that any elementoftyp e  can b e treated as b eing of

typ e  , the imp ort of matching is weaker. If <#  then any message senttoan

ob ject of the typ e  could also b e sent to an ob ject of typ e  .

MyType and matching are crucial to the expressiveness of PolyTOIL . My-

Type is often used in expressing the typ es of metho ds whose typ es will need

to change in sub classes. It app ears frequently in asso ciation with copy or clone

3

Roughly, an o ccurrence of an identi er is p ositive (or covariant) if it is on the left

side of an even numb er of function typ es, and is negative (or contravariant) if it is

on the left of an o dd numb er of function typ es. In particular, if the return typ e of a

function is MyType, then that o ccurrence of MyType is p ositive. On the other hand,

if a parameter typ e of a function is MyType, then that o ccurrence is negative.

class Node(n: Integer)

var

val = n: Integer;

next = nil: MyType;

methods

function getVal(): Integer {return val.clone() }

procedure setVal(newVal: Integer) {val := newVal.clone()}

function getNext(): MyType {return next}

procedure setNext(newNext:MyType) {next := newNext}

procedure attachRight(newNext: MyType) {self.setNext(newNext)}

end class;

class DbleNode(n: Integer)

inherits Node(n) modifying attachRight

var

prev = nil: MyType

methods

function getPrev():MyType {return prev}

procedure setPrev(newPrev: MyType){prev := newPrev}

procedure attachRight(newNext: MyType) {self.setNext(newNext);

newNext.setPrev(self) }

end class;

Fig. 1. Singly and doubly-linked no de classes in PolyTOIL.

metho ds and so-called binary metho ds { metho ds whose parameter should al-

ways b e the same typ e as the receiver. Bounded p olymorphism based on match-

ing proves to b e a very useful to ol in ob ject-oriented programming { so muchso

that when programming in PolyTOIL ,we found that it (in combination with

the use of MyType) almost completely replaced the use of subtyp e p olymorphism

asamechanism for pro ducing generic co de.

Figure 1 provides an example of Node and DbleNode class de nitions. Notice

that for n: Integer, class DbleNode(n) inherits from Node(n). The o ccurrences of

MyType in Node implicitly denote the typ e of ob jects generated by Node, while

in DbleNode they denote the typ e of ob jects generated by DbleNode. It follows

easily from the de nition of matching in PolyTOIL that the typ es generated

by these classes are in the matching relation. However they are not subtyp es

b ecause setNext and attachRight have parameters of typ e MyType.

Nevertheless it is p ossible to de ne a p olymorphic list class that, when in-

stantiated with the typ e of ob jects generated by Node, will generate singly-linked

lists, while if it is instantiated with the typ e of ob jects generated by DbleNode

will generate doubly-linked lists. (See [BSvG95] for the co de and details.) The

fact that these typ es are not subtyp es is not a handicap in using them in the

ways intended.

These results suggested to us that subtyping might not b e necessary at all.

At the same time, we b egan to feel that presenting programmers with b oth

the subtyping and matching hierarchies on typ es in a single language mightbe

confusing.

The pap er [GM96] in ECOOP `96 presented a language To oL, whichismore

general than PolyTOIL in that the b ound on p olymorphic typ es and classes could

be sp eci ed using either subtyping or matching, and typ e-checking of classes

could b e done assuming that MyType either matched or was a subtyp e of the

intended typ e of ob jects generated by the class. After exp erimenting with the

language, the authors decided the language was to o complex for programmers,

and suggested dropping matching. Based on our exp erience, we prefer instead to

give up subtyping. In the rest of this pap er, we describ e the language LOOM,

whichwe designed as a simpler replacement for PolyTOIL .

3 LOOM: Core Language

As a result of our concerns ab out the complexityof PolyTOIL ,wedevelop ed

the language LO O M. LO O M retains the syntax and match-b ounded p olymor-

phism of PolyTOIL , but completely abandons the subtyping relation in favor of

a simpli ed version of matching. As a whole, LO O M is a much simpler language

than its predecessor.

In abandoning subtyping, we also decided not to allow the typ es of inherited

metho ds to b e changed when overridden. While this may seem like a step back-

wards in the design of more exible typ e systems, our exp erience indicates that

the presence of the MyType construct (standing for the typ e of self ) combined

with match-b ounded p olymorphism provides sucient exibilityfor rede ning

metho ds in sub classes.

Because wewishtohave matching corresp ond to the changes in typ es allowed

in de ning sub classes, we provide a more restricted de nition of matching in

LO O M compared to that of PolyTOIL .We write ob ject typ es in LOOM in

the form

ObjectType

m1:T1;

...

mn:Tn

end;

or more compactly, ObjectType fm : T ; :::; m : T g.

1 1 n n

De nition 1. Given ob ject typ es ObjectType fm : T ; :::; m : T g and

1 1 n n

ObjectType fm : T ; :::; m : T g, de ne

1 1 k k

ObjectType fm : T ; :::; m : T g <# ObjectType fm : T ; :::; m : T g

1 1 n n 1 1 k k

i k  n. The relation <# is referred to as \matching".

In both PolyTOIL and [AC95], the matching relation allowed the typ es of

corresp onding metho ds to b e subtyp es. Since the corresp onding typ es must now

be the same, a matching typ e simply is an extension of the original. It might

seem that this would signi cantly impact the expressiveness of the language.

While there are some o ccasions where this restriction forces us to intro duce typ e

parameters, it is our exp erience that most of the time when we wish to have

a change in the typ e of a metho d, the use of MyType provides the necessary

change implicitly.

3.1 Hash Typ es Replace the Use of Subtyping

In ob ject-oriented languages, subtyping allows a value of one typ e to masquer-

ade as a value of a sup ertyp e. This p ermits the de nition of data structures and

op erations that treat heterogeneous ob jects with common functionality.Thisis

primarily used in two contexts. The rst is in applying functions to parame-

ters whicharesubtyp es of their declared typ e. The second is for assignments to

variables. While the rst problem can b e handled fairly elegantly with match-

b ounded p olymorphism, the second is essentially imp ossible in PolyTOIL with-

out subtyp e p olymorphism.

In those places where we mighthave passed in a parameter that was a subtyp e

of the declared typ e of the parameter, we could instead provide the function or

pro cedure with an extra typ e parameter that was b ounded (using matching) by

the originally declared typ e of the parameter. If wehad procedure p(w:Window)

in PolyTOIL taking a parameter of typ e Window , then it could also b e applied

to parameters which were subtyp es of Window . In LO O M we could rewrite

0

it as procedure p (T<# W indow ; w : T ) with appropriately mo di ed b o dy. This

pro cedure is actually now more general than the original b ecause it can be

applied to ob jects whose typ e merely matches that of Window rather than b eing

asubtyp e. In particular, if Window contains a metho d with a parameter of typ e

MyType, there are manytyp es which will match it, but none which are prop er

subtyp es.

This rewriting of programs has one ma jor disadvantage{itintro duces extra

typ e parameters into many of the metho d de nitions. One of the advantages of

subtyping is that it is p ossible to write one simple function de nition with a

parameter of a xed typ e, yet apply it to arguments of many more typ es. We

address this problem b elow.

The use of subtyping in assignment statements o ccurs frequently when de n-

ing heterogeneous data structures. In a language with subtyping, we can rela-

tively easily create a in which all data values are subtyp es of some

xed typ e. For instance, in programming a graphic user one mightwant

to maintain a heterogeneous list of windows. From the point of view of main-

taining the list, one need only require that each list element supp orts certain

window op erations. This can b e captured most naturally by assuming eachhas

atyp e which matches some general windowtyp e, rather than using subtyping.

(After all, some of the metho ds might include negative o ccurrences of MyType.)

We wish to b e able to handle this in our language.

In implementing these heterogeneous data structures, we often haveanin-

stance variable to whichwe wish to assign the values to b e stored in the structure.

Generally it is assumed that the typ e of the value to b e stored is a subtypeofthe

declared typ e of the variable. However, as ab ove, wehave found that assuming

it matches the declared typ e is often a b etter description of what is actually

needed. Unfortunately,we knownoway of mo deling the exibilityofsubtyping

for variable assignments using match-b ounded p olymorphism.

Tosolve these problems, weintro duce a new typ e, # , for  an ob ject typ e.

If a variable or formal parameter is declared to havetyp e # then it will b e able

4

to hold values of anytyp e matching  .

A simple example should illustrate the use of hash typ es. Supp ose wehavea

class in PolyTOIL with an instance variable aWindow of typ e Window, and a

metho d

procedure setWindow(newWindow:Window){aWindow := newWindow}

We can rewrite this in LO O M bychanging the typ e of aWindow to b e #W indow

and replacing the metho d by

procedure setWindow(newWindow:#Window){aWindow := newWindow}

Nowwe can pass a variable of anytyp e matching Window to the metho d. Note

that if Window had a binary metho d, then it has no subtyp es, so only ob jects of

typ e Window could b e passed in to the original setWindow.However, there will

b e manytyp es matching Window, so the revised metho d may b e more exible

than the original.

The typ e-checking rules Weakening and Subsump in App endix C state the

essential prop erties of these new typ es: If e has typ e  and <#  ,then e also

has typ e # .We refer to typ es of the form # as \hash" typ es, in reference to

the constructor.

We can now rewrite the pro cedure declaration ab ove nearly as simply as

0

with subtyping by writing procedure p (w :#W indow ) in place of the longer

p olymorphic de nition ab ove. Similarly we can declare a variable to havetyp e

# if it is to hold values with typ es that match  .

3.2 A Heterogeneous Ordered List Program in LO O M

Before presenting the syntax and typ e-checking rules of LO O M formally,we

provide an extended example of a heterogeneous list program. We begin by

de ning parameterized singly-linked and doubly-linked no des in LO O M , and

work up to de ning a class which can b e instantiated to provide either singly-

linked or doubly-linked heterogeneous ordered lists.

In Figure 2 we provide examples of parameterized HetNode and HetDou-

bleNode classes in LO O M . Unlike the earlier examples of No des from PolyTOIL ,

they are now parameterized bythetypeofvalue stored in the no de as well as

4

Some readers may nd it useful to think of # as an abbreviation for the typ e

9t<# :t of the second order lamb da calculus. (See [CW85 , MP88 ].)

class HetNode(T <# Object; v: #T)

var

value = v: #T;

next = nil: MyType;

methods

function getValue(): #T {return value.clone() }

procedure setValue(newValue: #T) {value := newValue.clone()}

function getNext(): MyType {return next}

procedure setNext(newNext:MyType) {next := newNext}

procedure attachRight(newNext: MyType) {self.setNext(newNext)}

end class;

class HetDbleNode(T <# Object; v: #T)

inherits HetNode(T,v) modifying attachRight

var

prev = nil: MyType

methods

function getPrev():MyType {return prev}

procedure setPrev(newPrev: MyType){prev := newPrev}

procedure attachRight(newNext: MyType) {self.setNext(newNext);

newNext.setPrev(self) }

end class;

Fig. 2. Polymorphic singly and doubly-linked no de classes.

the initial value for that no de. The upp er b ound Object on the typ e parameter T

is a built-in typ e whichevery ob ject typ e matches. (It is similar to class Object

of Java.) Because the instance variable value is declared to have typ e #T , it

can hold a value of anytyp e matching T. Similarly, the metho ds getValue and

setValue use hash typ es. On the other hand, the instance variables next and prev

can only hold values with typ e exactly MyType.Thus the next eld of an ob ject

generated by class HetNode can only hold no des, while the corresp onding eld

from class HetDbleNode can only hold doubly-linked no des. Note that for xed

U <# Object and u: #U , HetDbleNode(U,u) inherits from HetNode(U,u).

We can create new ob jects from the HetNode class by rst supplying the

parameterized class with actual parameters and then applying the new op eration

to it. Thus if U is an ob ject typ e and u:#U ,thennew HetNode(U,u) results in

the creation of a new no de ob ject whose value eld is initialized to u.

The typ e of ob jects is written using the ObjectType constructor. The typ e

functions HetNodeType and HetDbleNodeType de ned in Figure 3 describ e the

typ es of ob jects generated by the classes HetNode and HetDbleNode.

The keyword include used in the de nition of HetDbleNodeType indicates

that all metho ds of HetNodeType are included in HetDbleNodeType, as well as

the new metho ds declared there. This may b e thought of as a form of inheritance

for typ es. It is mo delled on a similar construct in Rapide [KLM94a], and is

HetNodeType(T <# Object) = ObjectType

getValue: Func():#T;

setValue: Proc(#T);

getNext: Func():MyType;

setNext: Proc(MyType)

attachRight: Proc(MyType)

end ObjectType;

HetDbleNodeType (T <# Object) = ObjectType include HetNodeType

getPrev: Func():MyType;

setPrev: Proc(MyType);

end ObjectType;

Fig. 3. Typ es for singly and doubly-linked no de classes.

essentially the same as the use of extends on interfaces in Java[AG96].

It follows from the de nition that if U <# Object,thenHetDbleNodeType(U)

<# HetNodeType(U). Of course, there is an implicit change of typ e resulting

from the o ccurrences of MyType in the typ es of getNext, setNext,and attachRight,

but the de nition of matching is sensitiveonlyto explicit changes in typ es.

The use of MyType ensures that instance variable, parameter, and return

typ es change appropriately when new classes are de ned by inheritance, and

new typ es are de ned using include.Thetyp e checking rule Msg in App endix C

sp eci es that when a message is sent to an ob ject whose corresp onding metho d

involves the typ e MyType, all o ccurrences of MyType in the metho d typ e are

replaced bythetyp e of the receiver. For example, if a setNext message is sentto

an ob ject, the actual parameter must have the same typ e as the receiver. In par-

ticular, if sn: HetNodeType(U) for some xed typ e U,thenthetyp e of parameter

newActualNext in sn.setNext(newActualNext) must also b e HetNodeType(U) for

the message send to be typ e correct. On the other hand, if dn: HetDbleNode-

Type(U), then the typ e of newActualNext in dn.setNext(newActualNext) must

be HetDbleNodeType(U).

OrdEltType = ObjectType

gt, eq: Func(#OrdEltType):Boolean;

...

end ObjectType;

OrdNodeType = HetNodeType(OrdEltType);

OrdDbleNodeType = HetDbleNodeType(OrdEltType)

Fig. 4. No de typ es for ordered elements.

class OrdList(N <# OrdNodeType)

var

head = nil: N;

methods

function find(match:#OrdEltType): Boolean

var

current: N;

{ current := head;

while (current != nil) & match.gt(current.getValue()) do

current := current.get_next()

end;

return (current != nil) & (current.getValue()).eq(matc h))}

procedure addNode(newNode:N)

...

end;

OrdListType(N <# OrdNodeType) = ObjectType -- parameterized type

find: Func(#OrdEltType): Boolean;

addNode: Proc(N);

end ObjectType;

Fig. 5. Heterogeneous linked list.

Wede neOrdEltType in Figure 4 to b e an ob ject typ e which includes op er-

ators which allow comparisons with elements of anytyp e matching OrdEltType.

We wish to construct a heterogeneous list, each of whose elements has a typ e

matching OrdEltType. The individual no des holding those values will havetyp e

OrdNodeType if wewishtohave a singly-linked list, or typ e OrdDbleNodeType

if we wish to have a doubly-linked list (see Figure 4). However, b ecause Ord-

DbleNodeType <# OrdNodeType,we can takeadvantage of the p olymorphism

by creating a list class which is parameterized so that the typ e of its no des is a

xed typ e whichmatches OrdNodeType.

In Figure 5 weprovide the de nition of a parameterized class which generates

heterogeneous lists of elements whose typ es all match OrdEltType. The gure also

includes the typ e function OrdListType which describ es the ob jects generated

by the class.

Because OrdList can be applied to any typ e which matches OrdNodeType,

we can easily instantiate the lists to b e either singly or doubly-linked. Thus

slist := new OrdList(OrdNodeType)

creates a new singly-linked heterogeneous list, while

d list := new OrdList(OrdDbleNodeType)

creates a new doubly-linked heterogeneous list. If elt has anytyp e whichmatches

OrdEltType then slist. nd(elt), slist.addNode(new Node(OrdEltType,elt)),

d list. nd(elt), and d list.addNode(new DbleNode(OrdEltType,elt)) are correctly

typ ed message sends which lo ok up or add new elements to singly or doubly-

linked lists.

3.3 Typ e Checking and Hash Typ es

The rules for forming legal typ e expressions and de ning matching in LO O M

are given in App endix B, while the most imp ortanttyp e-checking rules can b e

found in App endix C.

The typ e-checking rules for classes are in a slightly di erentstyle from those

in [BSvG95]. This slightvariation makes the pro of of typ e-safety somewhat sim-

pler. The keyword self is of typ e MyType, and represents the ob ject from the

outside. It is used as in the examples given earlier to send messages to the ob-

ject executing the co de, or it can b e used to pass the ob ject as a parameter to

a metho d of another ob ject. (The keyword self may b e omitted in terms of the

form self.m() in the implemented LOOM interpreter, as the interpreter can infer

where it needs to o ccur.) The keyword selfVar represents the record of instance

variables of the ob ject, which are only visible within the ob ject's metho ds. In

the examples given earlier in this pap er, if v is an instance variable, we have

chosen to simply write v rather than selfVar.v. Again the interpreter will infer

when this is needed and insert it if it is omitted.

The addition of hash typ es provides most of the original functionalityofsub-

typ e p olymorphism. It allows us to write heterogeneous data structures and to

write functions that op erate on all ob jects whose typ e matches their parameter.

However there are some new wrinkles in typ e checking that should b e noted.

As stated earlier, bytheWeakening and Subsumption typ e-checking rules, it

is p ossible for elements of a xed typ e  to b e assigned to a variable with typ e #

for <#  , but not vice-versa. Similar rules hold for the corresp ondence b etween

formal and actual parameters of functions and pro cedures.

We discussed ab ovethetyp e-checking rule for sending messages, Msg, which

app ears in App endix C. For that rule, we needed to know the exact typ e of the

receiver. But what happ ens if all we know ab out the receiver o is that it has

atyp e of the form # ? If the metho d to b e applied has a typ e  in whichall

o ccurrences of MyType are p ositive (e.g., MyType do es not occur as the typ e

of a parameter), then one can apply the same typing rule. That is, the typ e of

o.m is  [#=MyType ]. (See rule Msg# in the app endix.) It can b e shown via an

inductive pro of that this rule is sound. However, if the metho d typ e  includes

a negative(contravariant) o ccurrence of MyType, then the rule do es not hold.

A concrete example should help illustrate the reasons for the failure. Sup-

pose aNode has typ e #O r dN odeT y pe.ThenaNode.attachRight(bNode) will not

be well-typ ed. The value of aNode at run-time mightbeofanytyp e matching

OrdNodeType.Ifthevalue held in aNode actually has typ e OrdNodeType at run-

time, then the typ e of the parameter bNode must b e OrdNodeType. On the other

hand, if the typ e of the value held in aNode is actually OrdDbleNodeType at run-

time, then the typ e of the parameter bNode must instead b e OrdDbleNodeType.

Since we cannot determine the typ e of the value statically, we cannot deter-

mine which is the correct typ e for the parameter. (Note that having an actual

parameter with typ e #O r dN odeT y pe makes the situation even worse!)

Thus if the receiver of a message has a hash typ e, we cannot send it a binary

message, or indeed any message whose typ e involves an o ccurrence of MyType

in a contravariant p osition.

A practical consequence of this is that if wehave a heterogeneous data struc-

ture, as is the case in Figure 5 ab ove, we can only send non-binary messages to

its elements (at least in the absence of a typ e-case statement { or equivalent{

whichallows the run-time checking of typ es). One might susp ect that this is the

reason whythetyp e OrdEltType in the program has no binary metho ds. In fact,

this simply results from thinking through the logical design of these metho ds. If

ge and eq had typ es of the form func(#MyType ):Boolean,thentherewould b e

no way of comparing successive elements of the list, since their values could b e

of incomparable typ es matching OrdEltType. In that case one could not send a

comparison metho d to one using the other as a parameter. Thus it would b e a

logical mistake to try to use a binary metho d there.

It is also worth noting here that wewould b e stuck in this case in a language

supp orting subtyping as well. If the typ e  of elements in the list had a binary

metho d, then no prop er subtyp es of  would exist, forcing the list to b e homoge-

neous. In LO O M ,such binary metho ds mightexistin  , as long as they aren't

used in the metho ds of the heterogeneous data structure.

Finally in many cases where a binary metho d needs to b e sent to a parameter

x with a hash typ e of the form # , the function declaration can b e rewritten to

take an explicit typ e parameter t<#  and parameter x: t. In this waywehave

an explicit name for the typ e of x, and can provide an actual parameter for a

binary metho d with a parameter which is also of typ e t.

Thus while this restriction on typing message sends corresp onding to binary

metho ds seems to b e a limitation, the limitations are actually less severe than

in languages with subtyping.

4 Decidability, Natural Semantics, and Typ e Safety

In this section we outline some imp ortant results for LO O M whose details

will b e provided elsewhere. These include the decidabilityof typ e checking for

LO O M , the provision of natural semantics, and the pro of of typ e safety.

Pierce's [Pie92] results on the undecidabilityofsubtyping in the second-order

b ounded p olymorphic lamb da calculus has caused designers of languages sup-

p orting b ounded p olymorphism to b e concerned ab out whether their typ e sys-

tems are undecidable. While LO O M do es not supp ort subtyping, one mightbe

concerned that match-b ounded p olymorphism could lead to the same diculty.

Luckily this turns out not to b e the case. In fact the determination of whether

twotyp es match is relatively straightforward since one ob ject typ e matches an-

other only if the rst typ e contains all of the metho ds (with corresp onding typ es)

of the second. As usual it is straightforward to replace the general transitivity

rule for matching with a restricted rule which is computationally easy to deal

with (and in fact wehave included only this restricted rule in App endix B).

The algorithm for typ e checking terms is fairly straightforward. As with

PolyTOIL , the complexityoftyp e-checking is non-p olynomial in the worst case,

since in contrived families of examples the typ e of a term can grow exp onentially

fast in the length of the term. In practice we nd typ e checking in LO O M to

b e acceptably fast (at most quadratic in the size of the typ e).

In order to provethetyp e safetyofLOOM,we need to show that the typ e

system is consistent with a semantics for the language. We can de ne a natural

semantics for LOOM similar to that provided for PolyTOIL [BSvG95]. Once

de ned we can prove:

1. If a term of LO O M has typ e  (p ossibly under some assumptions on free

term and typ e variables) and if the evaluation of the term halts (when started

with an environment and state that are consistent with the assumptions),

5

then the value will also havetyp e  .

2. If a term is well-typ ed then the evaluation will not get \stuck". That is, it

will not get to a point in the evaluation where the partial result is not a

designated \reduced value", yet no computation rule applies.

The pro ofs of these results are similar to those in PolyTOIL , but are sim-

pler b ecause of the lackofsubtyping. The only terms which require extra work

are message sends to hash typ es, but a pro of by induction on the structure of

terms suces to show that the typ e-checking rule is sound. Needless to say,the

assumption that the metho d typ e includes only p ositive o ccurrences of MyType

is crucial to the pro of.

Details of the semantics, formal statement of the theorems, and the pro ofs

will b e given in an extended form of this pap er.

5 Adding Mo dules to LOOM

As programmers and language designers have gotten more exp erience with ob ject-

oriented languages, it has b ecome clearer that class b oundaries are not always

the correct abstraction layer for large programs. Interestingly it is the hybrid

languages which have grown from ADT-style languages whichhave often pro-

vided the b est supp ort for this mo dularity.Thus Ada 95 [Int95] and Mo dula-3

+

[CDG 88] have intro duced mo dule structures which are distinct from classes.

Pure ob ject-oriented languages like Smalltalk and Ei el have generally chosen

to identify classes with mo dules, though newer languages like Theta [DGLM94]

(which can b e seen as a descendant of the ADT-style language, Clu) and Java

[AG96]havealsochosentoprovide mo dules (called packages in Java).

5

If  involves free typ e variables then the typ e of the value will havea typ e obtained by

replacing the free typ e variables of  by corresp onding values from the environment.

Mo dules provide three imp ortant functions in programming languages:

1. They provide a way of organizing co de into manageable pieces and help with

name-space managementby only exp orting names that are needed elsewhere.

2. They provide imp ortant abstraction barriers, lessening the dep endence of a

unit on the implementation details of another unit.

3. They provide supp ort for separate compilation, aiding the programmer in

debugging large programs as well as making it p ossible to provide reusable

co de in libraries in such a way that the original source co de need not be

revealed.

With strong language supp ort for mo dules it should b e p ossible to change the

implementation of a typ e without changing its public interface and without

requiring recompilation of other mo dules which imp ort it. See [Jon96] for a

more detailed discussion of mo dules.

Wehavechosen to follow the lead of languages like those in the Mo dula and

Ada families and provide mo dule interfaces which can be completely separate

from the mo dule implementation (e.g., the interface can b e compiled b efore the

implementation is written). A key issue is to provide a mechanism for revealing

in the interface as muchor as little as desired ab out the details of the imple-

mentation of a typ e.

In ADT-style languages it is typical for typ e de nitions in interfaces to con-

sist either of manifest typ es, in which all details of the typ e de nition are re-

vealed, or opaque typ es, in which only the name of the typ e is revealed. However

in ADT-style languages, op erations are de ned externally from the typ e itself.

Thus an opaque typ e will b e accompanied by a collection of names of constants,

functions, and pro cedures related to it that are to be exp orted (though their

implementations are typically hidden).

In ob ject-oriented languages, however, ob ject typ es include the names and

typ es of their metho ds. In ADT-style languages it is easy to reveal only certain

op erations, leaving others hidden in the implementation mo dule. Wecanemulate

this in ob ject-oriented languages byproviding partial revelations of ob ject typ es

as is done in Mo dula-3. That is, for each ob ject typ e we only list those metho ds

whichwe wish to publicly advertise. This can b e expressed using the matching

relation from LOOM.

The following example is similar to one presented in [PT93]. If we declare

IntSetType <# ObjectType

add: proc(Integer);

remove: proc(Integer);

contains: func(Integer):Boolean;

intersect: proc(MyType)

end;

in an interface, then weknowthatIntSetTyp e has metho ds add, remove, con-

tains,andintersect with the appropriate typ es. As b efore, we note that subtyp-

ing would not b e an appropriate relation (even if it was supp orted in LO O M)

b ecause the fact that intersect has a parameter of typ e MyType implies that the

given ob ject typ e has no prop er subtyp es!

LO O M ,like PolyTOIL ,allows the programmer to lab el metho ds as either

Visible or Hidden, dep ending on whether or not we wish them to b e available

6

outside of the ob ject's own metho ds. Also an ob ject's instance variables are

not accessible outside the ob ject's metho ds. Why then do we need the extra

mechanism of partial revelations? The reason is that some ob jects might need

to provide extra metho ds which are only accessible to a limited number of other

typ es of ob jects. This is exactly the idea b ehind C++'s friends and is similar to

the provision of di erentlevels of access in Ada 95 and Java.

Let us continue with the example ab ove of sets of integers. In order to imple-

ment the intersection op eration eciently wemay need to have more access to

the representation of the sets. App endix A contains an example of a collection

of LOOM mo dules which supp orts the ecient implementation of integer sets

as ordered lists.

There are several p oints worthy of remark in this example. First notice that

OrdListType is a manifest typ e. The user has full access to the typ e and to

the class OrdListClass which generates ob jects of that typ e. However the typ e

IntSetType is only partially revealed. Inside the implementation mo dule it is

de ned as an extension of OrdListType (and hence matches OrdListType ), but

that information is not available outside of the implementation mo dule. Hence

one may not deduce in any other mo dule that IntSetType <# OrdListType. This

represents go o d programming practice since one should not in general b e able to

use list op erations on sets. Notice also that b ecause OrdListType is not exp orted

by Interface SetOfInt, the name space is not cluttered up with details ab out

lists.

A second imp ortant p oint ab out this example is that our (ecient) imple-

mentation of intersect dep ends on b eing able to use the fact that IntSetType is

implemented as an ordered list. If, for example, all of the list op erations (suchas

rst, next,anddeleteCur )were hidden metho ds, wewould not b e able to send

the corresp onding messages to the parameter other. If there were metho ds of

other classes which also needed access to these non-exp orted metho ds, wewould

simply include their de nitions in the same mo dule. Thus we can achieve the

e ect of C++'s friends without letting the non-exp orted metho ds escap e the

mo dule b oundary.

This technique for providing information hiding while providing access by

op erations at the same level of abstraction is similar to that suggested in [PT93]

and [KLM94b], where b ounded existential quanti ers based on subtyping are

used to p erform the information hiding.

In summary, our implementation of mo dules in LOOM allows the program-

mer to sp ecify howmuch information ab out an ob ject typ e is revealed to other

program units. While it is p ossible to havea totally opaque typ e, this should

6

For simplicity,wehave not lab eled the metho ds in the earlier examples, though all

would b e lab eled as Visible. Our use of Visible corresp onds to C++ and Java's public,

while Hidden corresp onds to their protected.

b e relatively rare with the ob ject-oriented style of programming. The user can

reveal all of the details of a typ e de nition byproviding a manifest typ e, or may

reveal only a p ortion of the typ e byproviding a matching b ound on the typ e.

Function, pro cedure, class, and other constant declarations can also b e exp orted

by placing them in a mo dule interface. Our mo dule design satis es all of the

goals listed at the b eginning of this section.

6 Evaluation of LOOM

One of the most dicult decisions to make in designing a

is not so much what features should be included, but rather which features

can (or should) be excluded. Based on our previous work, we concluded that

subtyping was a feature that could b e excluded from ob ject-oriented languages.

In this pap er we presented the language LO O M , which dropp ed subtyping in

favor of matching, and added hash typ es.

Aside from subtyping, features of LOOM include all of those in our earlier

language PolyTOIL . Because of the lackofsubtyping, we decided not to allow

7

typ es of metho ds to b e changed when de ning sub classes. Similarly,matching

now requires corresp onding metho d typ es to b e the same, rather than subtyp es.

To replace other uses of subtyping weintro duced a new typ e constructor which

can b e applied to ob ject typ es to obtain \hash typ es". With the addition of the

hash typ es, the elimination of subtyping has very little impact on the expres-

siveness of the language.

Another advantage of LO O M is that the matching relation is relatively

trivial, only allowing the addition of new metho ds to ob ject typ es, as compared

to subtyping, which is de ned on all typ es and is often quite complex. The

covariant and contravariant rules for subtyping functions are a go o d example of

the complexity of subtyping that we can simply ignore in LO O M .

Binary metho ds have b een hard to express in most statically-typ ed ob ject-

oriented programming languages b ecause they seem to require a MyType term

representing the typ e of self,yet MyType and subtyping havenotinteracted well.

+

See [BCC 96] for an exp osition of the diculties of handling binary metho ds in

statically-typ ed ob ject-oriented languages. In that pap er, matching is suggested

as one way of getting around these diculties, but it is also criticized as not

providing supp ort for heterogeneous data structures. In this pap er wehaveshown

howtoprovide that supp ort by the use of hash typ es.

One p ossible disadvantage of LO O M is that the programmer must explicitly

mark the typ es of variables and formal parameters which are allowed to hold

values of more than one typ e by declaring them with hash typ es. Variables and

parameters with non-hash typ es are only allowed to hold values of the typ e with

which they are declared. The programmer is required to \plan ahead" which

slots are allowed to hold values whichmatch b ecause the typing rules for message

sending are di erent for hash typ es than for regular typ es. It is worth noting in

7

An early version of LOOM did allowtyp es to b e changed, but we decided that the

gains were not worth the added complexity.

this regard that Ada 95 [Int95] also requires the programmer to mark the typ es

of variables and parameters with the \class "suxifvalues which are sub classes

of the declared typ e maybeused.

A complication of LO O M compared to PolyTOIL is that binary messages

may not be sent to hash typ es. As discussed in the previous section, this has

little practical impact since binary metho ds are generally not appropriate for

heterogeneous data, and match-b ounded p olymorphism can usually b e used in

place of hash typ es where binary metho ds are needed.

We noted that the typ e-checking algorithm for LO O M is decidable, with

low complexity in practice. Also, the static typ e system for LO O M guarantees

that no typ e errors will o ccur during the execution of typ e-checked programs, so

LO O M is typ e-safe.

LO O M also provides signi cant features for information hiding. All instance

variables are hidden from clients, while metho ds are marked as b eing either

visible or hidden in order to determine their visibilityto clients. All instance

variables and metho ds are visible to inheritors. We describ ed brie y the mo dule

facilityin the language which provides for separate compilation, restriction of

the scop e of names, and information hiding. Like Mo dula-3, it provides extra

supp ort for information hiding by the use of partial revelations of typ es. This

ne control over information hiding can b e used to provide ob jects de ned in the

mo dule access to more features than those outside, providing a feature similar to

C++'s friends. This also allows more ecient implementation of binary metho ds.

We are currently examining mechanisms to allow mo dules to supp ort multiple

interfaces. This would make it p ossible to provide di erent views of a mo dule to

di erentclients. For instance, a client wishing to de ne a sub class of a class in

a mo dule will need much more detailed information ab out the sup erclass than a

clientwhich simply wishes to b e able to generate ob jects from the class and use

them.

We have implemented an interpreter for LOOM, which is based on the

natural semantics of the language. In spite of the seemingly radical step of elimi-

nating subtyping, our exp erience is that LO O M provides a conceptually simpler

language than PolyTOIL , yet provides essentially the same expressiveness as

the earlier language. It may b e time to rethink the notion that subtyping is an

essential part of ob ject-oriented languages.

Acknow ledgements: The LO O M language design is due to Bruce and Petersen.

Amorecomplete description of the language design, type-checing rules, natural

semantics, and the analysis of complexity of type-checking can be found in Pe-

tersen's honors thesis [Pet96 ]. The proof of was done by Fiech with

the assistanceof Bruce, and was based on a similar proof for PolyTOIL . The

LO O M implementation was primarily accomplished by Petersen with assistance

from Hilary Browne, and was based on the PolyTOIL interpreter written by

Robert van Gent and Angela Schuett, with assistancefrom Petersen and Jasper

Rosenberg.

References

[AC95] Martin Abadi and . On subtyping and matching. In Proceed-

ings ECOOP '95, pages 145{167, 1995.

[AG96] Ken Arnold and James Gosling. Java. Addison Wesley, 1996.

[AvdL90] Pierre America and Frank van der Linden. A parallel ob ject-oriented lan-

guage with inheritance and subtyping. In OOPSLA-ECOOP '90 Proceed-

ings, pages 161{168. ACM SIGPLAN Notices,25(10), Octob er 1990.

+

[BCC 96] Kim B. Bruce, Luca Cardelli, Giusepp e Castagna, The Hopkins Ob jects

Group, Gary T. Leavens, and Benjamin Pierce. On binary metho ds. The-

ory and PracticeofObject-Oriented Systems, 1996. to app ear.

[Bru93] K. Bruce. Safe typ e checking in a statically typ ed ob ject-oriented pro-

gramming language. In Proc. ACM Symp. on Principles of Programming

Languages, pages 285{298, 1993.

[Bru94] K. Bruce. A paradigmatic ob ject-oriented programming language: design,

static typing and semantics. Journal of , 4(2):127{

206, 1994. An earlier version of this pap er app eared in the 1993 POPL

Pro ceedings.

[BSvG95] Kim B. Bruce, Angela Schuett, and Rob ert van Gent. PolyTOIL: A typ e-

safe p olymorphic ob ject-oriented language, extended abstract. In ECOOP

'95, pages 27{51. LNCS 952, Springer-Verlag, 1995.

+

[CDG 88] L. Cardelli, J. Donahue, L. Galssman, M. Jordan, B. Kalsow, and

G. Nelson. Mo dula-3 rep ort. Technical Rep ort SRC-31, DEC systems

Research Center, 1988.

[CHC90] William R. Co ok, Walter L. Hill, and Peter S. Canning. Inheritance is

not subtyping. In Proc. 17th ACM Symp. on Principles of Programming

Languages, pages 125{135, January 1990.

[CW85] L. Cardelli and P.Wegner. On understanding typ es, data abstraction, and

p olymorphism. Computing Surveys, 17(4):471{522, 1985.

[DGLM94] Mark Day, Rob ert Grub er, Barbara Liskov, and Andrew C. Meyers. Ab-

straction mechanisms in Theta. Technical rep ort, MIT Lab oratory for

Computer Science, 1994.

++

[ES90] Margaret A. Ellis and Bjarne Stroustrop. The annotated C reference

manual. Addison-Wesley, 1990.

[GM96] Andreas Gawecki and Florian Matthes. Integrating subtyping, matching

and typ e quanti cation: A practical p ersp ective. In ECOOP '96, pages

26{47. LNCS 1098, Springer-Verlag, 1996.

[Int95] Intermetrics. Ada 95 Reference Manual, version 6.0. 1995.

[Jon96] Mark P. Jones. Using parameterized signatures to express mo dular struc-

ture. In 23rd ACM Symp. Principles of Programming Languages, pages

68{78, 1996.

[KLM94a] Dinesh Katiyar, David Luckham, and John Mitchell. Atyp e system for

prototyping languages. In 21st ACM Symp. Principles of Programming

Languages, pages 138{150, 1994.

[KLM94b] Dinesh Katiyar, David Luckham, and John Mitchell. Atyp e system for

prototyping languages. In Conference Record of POPL '94: 21st ACM

SIGPLAN{SIGACT Symposium of Principles of Programming Languages,

Portland, Oregon, pages 138{150. Asso ciation for Computing Machinery,

January 1994.

[LP91] Wilf LaLonde and John Pugh. Sub classing 6= subtyping 6= is-a. Journal

of Object-OrientedProgramming, pages 57{62, January 1991.

[Mey92] B. Meyer. Ei el: the language. Prentice-Hall, 1992.

[MMMP90] O. Madsen, B. Magnusson, and B. Moller-Pedersen. Strong typing of

ob ject-oriented languages revisited. In OOPSLA-ECOOP '90 Proceedings,

pages 140{150. ACM SIGPLAN Notices,25(10), Octob er 1990.

[MP88] J.C. Mitchell and G.D. Plotkin. Abstract typ es have existential typ es.

ACM Trans. on Programming Languages and Systems, 10(3):470{502,

1988. Preliminary version app eared in Proc. 12th ACM Symp. on Princi-

ples of Programming Languages, 1985.

[Pet96] Leaf Petersen. A module system for LOOM. Williams College Senior

Honors Thesis, 1996.

[Pie92] Benjamin C. Pierce. Bounded quanti cation is undecidable. In Proc 19th

ACM Symp. Principles of Programming Languages, pages 305{315, 1992.

[PT93] Benjamin C. Pierce and David N. Turner. Statically typ ed friendly func-

tions via partially abstract typ es. Technical Rep ort ECS-LFCS-93-256,

University of Edinburgh, 1993.

[Sny86] A. Snyder. Encapsulation and inheritance in ob ject-oriented programming

languages. In Proc. 1st ACM Symp. on Object-OrientedProgramming Sys-

tems, Languages, and Applications, pages 38{46, Octob er 1986.

[Tes85] L. Tesler. Ob ject Pascal rep ort. Technical Rep ort 1, Apple Computer,

1985.

A Sample LOOM Program for Integer Sets Using

Mo dules

Arow of \*"s indicates a mo dule b oundary.Theintersection metho d of SetOfInt

is destructive { the receiver of the message is up dated to hold the value of the

intersection.

Interface IntOrdList;

type

OrdListType = ObjectType

first: proc();

next: proc();

off: func():Boolean; -- is current elt off end of list?

add: proc(Integer);

deleteCur: proc(); -- current is next elt after deleteCur

contains: func(Integer):Boolean;

getCur: func():Integer

end;

OrdListClassType = ClassType ... end;

-- class types include instance variable and method types

const

OrdListClass: OrdListClassType;

end;

****************************************************

Interface SetOfInt;

type

IntSetType <# ObjectType

add: proc(Integer);

remove: proc(Integer);

contains: func(Integer):Boolean;

intersect: proc(MyType)

end;

const

function newSet(): IntSetType;

end; -- Interface SetOfInt

****************************************************

Module Implements SetOfInt import IntOrdList;

-- SetOfInt is implemented as a specialized ordered list in order

-- to make the methods find and intersect more efficient.

type

IntSetType = ObjectType include IntOrdList::OrdListType

remove :proc(Integer);

intersect: proc(MyType)

end;

ListSetClassType = ClassType

include IntOrdList::OrdListClassType;

methods visible

remove :proc(Integer);

intersect: proc(MyType) end;

const

ListSetClass = class inherit IntOrdList::OrdListClass

methods visible

procedure remove(elt:Integer) is

begin

if find(elt) then deleteCur()

end;

procedure intersect(other:MyType) is

-- destructive intersection

begin

first();

other.first();

while (not off()) and (not other.off) do

if getCur() < other.getCur() then

deleteCur()

else if getCur() > other.getCur then

other.next()

else

next();

other.next()

end -- else if

end -- if

end -- while

while not off() do

deleteCur()

end -- while

end -- function

end; -- class

function newSet():IntSetType;

begin

return new(ListSetClass)

end;

end -- Module

B Typ e Formation and Matching Rules

There are rules which determine whichtyp e expressions are well-formed. While

there is not ro om to include these in this extended abstract, the well-formed typ e

expressions are the following: a typ e variable or constant, a function typ e of the

form Func( ): , a p olymorphic function typ e Func(s <#  ): where  is an

ob ject typ e or typ e variable, a regular or p olymorphic pro cedure typ e, a record

typeoftheformfm :  ; :::; m :  g, an ob ject typ e of the form ObjectType 

1 1 n n

(for  a record typ e), an expression of the form ClassType( , ) (for  and 

record typ es) which represents the typ e of a class whose instance variables have

typ e  and metho ds havetyp e  , or an expression of the form # (where  is

an ob ject typ e or variable).

Reference typ es are generated automatically by the system from variable

declarations. The typ e of a variable holding values of typ e  is written as ref  .

We say that fm :  ; :::; m :  g extends fm :  ; :::; m :  g, if n  k .

1 1 n n 1 1 k k

Matching is only de ned on ob ject typ es and variables.

Var( <#) C [ft<#  g`t<# ;

C ` <# O bj ect

Ref l ( <#)

C ` <# ;

C ` <#

T r ans( <#) ;

C [ft<#  g`t<#

0

 extends 

Obj ectT y pe( <#) ;

0

C ` O bj ectT y pe  <# O bj ectT y pe 

C Selected Typ e-checking Rules for LO O M

C is a collection of typ e constraints of the form t<#  ,whileE is a collection of

typ e assignments to identi ers. Wehave omitted many of the rules which are the

same as for PolyTOIL. In particular wehave omitted the rules for declarations

and most commands aside from assignment.

C; E ` x: ref ; C; E ` M : 

Assn

C; E ` x:= M : COMMAND

Var C; E ` x: ; if E (x)=

C; E [fv :  g` Block: 

F unction

C; E ` function (v :  ) B l ock : (Func ( ):  )

where  may b e of the form # .

C [ft<# g;E ` B l ock : 

BdPolyFunc

C; E ` function (t<# ) Block: (F unc (t<# ):  )

C; E ` f : F unc( ): 

C; E ` M : 

F uncAppl

C; E ` f (M ): 

C; E ` f : Func(t<# ): 

C ` <#

B dP ol y F uncAppl

C; E ` f [ ]:  [=t]

C; E ` a :  ; for 1  i  n

i i

R ecor d

C; E `fv = a ; :::; v = a g: fv :  ; :::; v :  g

1 1 n n 1 1 n n

C; E ` a: T; C ` T extends fv :  ; :::; v :  g

1 1 n n

Proj if 1  i  n

C; E ` a:v : 

i i

IV METH METH

C ;E ` a: ; C ;E ` e: 

C l ass

C; E ` class(a; e): ClassType (;)

IV

where C = C [fMyType <# O bj ectT y pe  g;

METH IV

C = C [fSelfVarType extends MkRef ( )g;

METH

E = E [fself : MyType ; selfVar : SelfVarType g

MkRef fv :  ; :::; v :  g = fv : ref  ; :::; v : ref  g

1 1 n n 1 1 n n

Neither MyType nor SelfVarType may o ccur free in C or E .

 and  must b oth b e record typ es,

while the comp onents of  must b e function typ es.

C; E ` c: ClassType (;)

Obj ect

C; E ` new c: Obj ectT y pe 

C; E ` o: ; C ` <# O bj ectT y pefm:  g

Msg

C; E ` o ( m:  [ =MyType ]

C; E ` o:#Obj ectT y pefm :  ; :::; m :  g

1 1 n n

Msg#

C; E ` o ( m :  [#Obj ectT y pefm :  ; :::; m :  g=MyType ]

i i 1 1 n n

Only if all o ccurrences of MyType in  are p ositive.

i

C; E ` c: ClassType (fv :  ; :::; v :  g; fm :  ; :::; m :  g);

1 1 m m 1 1 n n

IV IV 0

C ;E ` a :  ; C ;E ` a :  ;

m+1 m+1 1

1

METH METH METH METH 0

C ;E ` e :  ; C ;E ` e : 

n+1 n+1 1

1

Inherits

C; E ` class inherit c mo difying v ;m ;

1 1

0

(fv = a :  ;v = a :  g;

1 1 m+1 m+1 m+1

1

0

fm = e :  ;m = e :  g):

1 1 n+1 n+1 n+1

1

ClassType (fv :  ; :::; v :  g;

1 1 m+1 m+1

fm :  ; m :  ; :::; m :  g)

1 1 2 2 n+1 n+1

IV

where C = C [fMyType <# O bj ectT y pe fm :  ; :::; m :  gg;

1 1 n+1 n+1

METH

C =

IV

C [fSelfVarType extends MkRef (fv :  ; :::; v :  g)g

1 1 m+1 m+1

METH

E = E [fself : MyType ; selfVar : SelfVarType ;

super : MyType ! SelfVarType !fm :  ; :::; m :  gg

1 1 n n

Neither MyType nor SelfVarType may o ccur free in C or E .

C; E ` e: 

W eak ening

C; E ` e:#

C ` <# ; C; E ` e:#

S ubsump

C; E ` e:#

A

This article was pro cessed using the L T X macro package with LLNCS style. E