Modular Object-Oriented Programming with Units and Mixins
Mo dular Ob ject-Oriented Programming with Units and Mixins
Rob ert Bruce Findler Matthew Flatt
Department of Computer Science
Rice University
Houston, Texas 77005-1892
class languages follow from a single language design prin- Abstract
ciple: specify connectionsbetween modules or classes sepa-
Mo dule and class systems haveevolved to meet the demand
rately from their de nitions.
for reuseable software comp onents. Considerable e ort has
The shared principle of separating connections from def-
b een invested in developing new mo dule and class systems,
initions makes units and mixins synergistic. When units
and in demonstrating howeach promotes co de reuse. How-
and mixins are combined, a programmer can exploit the en-
ever, relatively little has b een said ab out the interaction of
capsulation and linking prop erties of units to control the
these constructs, and how using mo dules and classes together
application of mixin extensions (e.g.,tochange the class
can improve programs. In this pap er, we demonstrate the
extended by a particular mixin).
synergy of a particular form of mo dules and classes|called
In Section 5, we motivate in more detail the design b e-
units and mixins, resp ectively|for solving complex reuse
hind MzScheme's units and mixins, but their synergy is b est
problems in a natural manner.
demonstrated with an example. The bulk of this pap er
therefore presents an in-depth example, showing how the
synergy of units and mixins solves an old extensibility prob-
1 Intro duction
lem [7, 40] in a natural manner. Section 2 describ es the
extensibili ty problem, and Section 3 develops a rough solu-
Mo dule and class systems b oth promote co de reuse. In the-
tion the problem using conventional classes. Section 4 intro-
ory,many uses of classes can b e simulated with mo dules,
duces units and mixins to re ne and complete the solution.
and viceversa. Exp erience shows, however, that program-
Sections 5 and 6 extract lessons from the example for the
mers need b oth constructs b ecause they serve di erentpur-
design of mo dular ob ject-oriented programming languages.
p oses [43]. A mo dule delineates b oundaries for separate de-
Finally, Section 7 relates our work to other research.
velopment. A class p ermits ne-grained reuse via selective
inheritance and overriding.
Since mo dules and classes aid di erent patterns of reuse,
2 The Extensibility Problem
mo dern languages provide separate constructs for each. Un-
fortunately, the reuse allowed byconventional mo dule and
The following table summarizes the extensibili ty problem:
class systems is limited. In these systems, mo dules and
original variants extension
classes are hard-wired to a sp eci c context, i.e., to sp eci c
z }| { z }| {
mo dules or to a sp eci c sup erclass.
2 ;
In previous work, we separately describ ed the novel mo d-
(
ule and class systems in MzScheme [12]. MzScheme's mo d-
original draw draw( 2 ) draw( ) draw( ; )
ules [13], called units , are roughly likeJava packages, ex-
op erations
cept that units are linked through an external linking sp ec-
shrink shrink( 2 ) shrink ( ) shrink ( ; )
n
i cation, instead of through a xed internal sp eci cation.
extension
rotate rotate( 2 ) rotate ( ) rotate ( ; )
MzScheme's ob ject language [14] provides mixins , whichare
likeJava classes except that a mixin is parameterized over
its sup erclass, so it can b e applied multiple times to create
The p ortion of the table contained in the dotted b ox repre-
di erent derived classes from di erent base classes. The ad-
sents a program comp onentthatprovides several op erations,
vantages of units and mixins over conventional mo dule and
draw and shrink, on a collection of data, geometric shap es
like squares and circles. A programmer may wish to use
This researchwas partially supp orted by a Lo dieska Sto ckbridge
such a comp onent in three di erentcontexts:
Vaughan Fellowship, NSF grants CCR-9619756, CDA-9713032,and
CCR-9708957, and a Texas ATP grant.
1. The programmer may wish to include the comp onent
as is.
2. The programmer may wish to extend the datatyp e
with a variant, rep ositioned shap es, and adapt the col-
lection of op erations accordingly.
3. The programmer may wish to add a new op eration,
To app ear: ICFP { Sept. 27-29 1998, Baltimore, MD
rotate. 1
? ? ? ? ? ? ? ?
? ? ?
Client
Client Client Client Client
(a) Original Datatyp e
(b) New Variant (c) New Op eration
Figure 1: Extensible programming on datatyp es
Toavoid duplicate maintenance, or b ecause the comp onent 3 Extensible Programming with Classes
is acquired in ob ject form, the comp onentmust b e organized
Figure 1 outlines our solution to the extensibili ty problem:
so that programmers can add b oth new forms of data and
new op erations without modifying or recompiling
Diagram (a) represents the original comp onent. The
rhombus stands for the datatyp e, and the rectangles
the original program comp onent, or
denote the datatyp e's variants. The oval is a clientof
its existing clients.
the datatyp e comp onent.
Such a program organization dramatically increases the p o-
Diagram (b) shows the datatyp e extended with a new
tential for software reuse and enables the smo oth integration
variant. The extension is contained in the right inner
of proprietary mo dules.
dashed b ox. The solid b ox on the left represents the
Neither standard functional nor ob ject-oriented strate-
unmo di ed datatyp e co de from (a). The original client
gies o er a satisfactory way to implement the comp onent
is also preserved, and a new client of the datatyp e
and its clients. In a functional language, the variants can b e
exploits the variant extension.
implemented as a typ e, with the op erations as functions on
Diagram (c) shows extension in the other direction:
the typ e. Using this approach, the set of op erations is easily
adding a new op eration to the datatyp e. As b efore,
extended, but adding a new variant requires mo difying the
the extension is implemented by the inner dashed b ox
functions. In an ob ject-oriented language, the variants can
while the solid b ox represents the unmo di ed existing
b e implemented as a collection of classes, with the op era-
implementation from (b). The new squares in the ex-
tions as metho ds common to all of the classes. Using this
tension represent the implementation of the op eration
approach, the datatyp e is easily extended with a new vari-
for eachvariant. The existing clients have not b een
ant, but adding a new op eration is typically implemented
mo di ed, although they now refer to the extended vari-
by mo difying the classes.
ants.
The existing literature provides three solutions to the
problem. Kuhne's [24] solution, which relies on generic pro-
The remainder of this section develops a concrete example,
cedures with double-dispa tchin g, can interfere with the hi-
an evolving shap e program [11, 23]. Since Figure 1 can b e
erarchical structure of the program. Palsb erg and Jay's [32]
approximated using conventional classes, we rst use only
solution is based on re ection op erators and incurs a sub-
language features available in a typical ob ject-oriented lan-
stantial run-time p enalty. Krishnamurthi, Felleisen, and
guage. But, classes are not enough; Section 4 intro duces
Friedman [11, 23] prop ose an ecient solution that works
units and mixins to complete the solution.
with standard class mechanisms, but it requires the imple-
mentation (and maintenance) of a complex programming
3.1 Shap e Datatyp e
proto col. All of these solutions are partial b ecause they do
not address the reuse of clients. In contrast, the combination
Initially, our shap e datatyp e consists of three variants and
of units and mixins solves the problem simply and elegantly,
one op eration: rectangles, circles, and translated shap es for
and it addresses the reuse of b oth the original comp onent
drawing. The rectangle and circle variants contain numb ers
and its clients.
that describ e the dimensions of the shap e. The translated
variant consists of twonumbers, and , and another
x y 2
(define Shape (interface () draw)) (define BB-Shape (interface (Shape) bounding-box))
(define Rectangle (define BB-Rectangle
(class* null (Shape)(width height) (class* Rectangle (BB-Shape)(width height)
(public (public
[draw (lambda (window x y) :: :)]))) [bounding-box
(lambda () (make-object BB 0 0 width height))])
(define Circle (sequence (super-init width height))))
(class* null (Shape)(radius)
(public (define BB-Circle
[draw (lambda (window x y) :: :))])) (class* Circle (BB-Shape)(radius)
(public
(define Translated [bounding-box
(class* null (Shape)(shape ) (lambda () (make-object BB (- radius)(- radius)
x y
(public radius radius))])
[draw (lambda (window x y) (sequence (super-init r))))
(send shape draw
window (+ x )(+y )))]))) (define BB-Translated
x y
(class* Translated (BB-Shape)(shape )
x y
(public
Figure 2: Shap e classes
[bounding-box (lambda () :::)])
(sequence (super-init shape ))))
x y
(define BB-Union
(define display-shape
(class* Union (BB-Shape)(left right)
(lambda (shape)
(public
(if (not (is-a? shape Shape))
[bounding-box (lambda () :::)])
(error \expected a Shape"))
(sequence (super-init left right))))
(let ([window :::])
(send shape draw window 00))))
(define BB
(class* null () (left top right bottom)
(display-shape (make-object Translated
:::))
(make-object Rectangle 50 100)
30 30))
(define display-shape
(lambda (shape)
Figure 3: Two shap e clients
(if (not (is-a? shape BB-Shape))
(error \expected a BB-Shape"))
(let*([bb (send shape bounding-box)]
[window :::][x :::][y :::])
shap e. For all variants, the drawing op eration takes a des-
(send shape draw window x y))))
tination window and twonumb ers describing a p osition to
draw the shap e.
Figure 5: Op eration extension
The shap e datatyp e is de ned by the Shap e interface and
implemented by three classes: Rectangle, Circle and Trans-
lated. Each sub class declares a draw metho d, whichisre-
quired to implementtheShap e interface. Figure 2 shows
3.2 Variant Extension
the interface and class de nitions using MzScheme's class
To create more interesting con gurations of shap es, we ex-
system. (MzScheme's class system is similar to Java's; for
tend the shap e datatyp e with a new variant representing
details, see the App endix.)
the union of two shap es. Following the strategy suggested
Figure 3 contains clients for the shap e datatyp e. The
in Figure 1 (b), wede neanewUnion class derived from
function display-shape consumes a shap e and draws it in
Shap e. Figure 4 de nes the Union class, and shows an ex-
a new window. The nal expression creates a shap e and
pression that uses the new class.
displays it. As the shap e datatyp e is extended, we consider
The simplici tyofthevariant extension re ects the nat-
how these clients are a ected.
ural expressiveness of ob ject-oriented programming. The
ob ject-oriented approach also lets us add this variant with-
out mo difying the original co de or the existing clients in
(define Union
Figure 3.
(class* null (Shape)(left right)
(public
3.3 Op eration Extension
[draw (lambda (window x y)
(send left draw window x y)
Shap es lo ok b etter when they are drawn centered in their
(send right draw window x y))])))
windows. We can supp ort centered shap es by adding the
op eration bounding-box ,which computes the smallest rect-
(display-shape
(make-object Union
angle enclosing a shap e.
(make-object Rectangle 10 30)
We add an op eration to our shap e datatyp e by de ning
(make-object Translated
four new classes, each derived from the variants of Shap e in
(make-object Circle 20) 30 30)))
Section 3.2. Figure 5 de nes the extended classes BB-Circle,
BB-Rectangle, BB-Translated,and BB-Union,each provid-
Figure 4: Variant extension and a new client
ing the bounding-box metho d. It also de nes the BB-Shap e 3
(set! factory :::) (define Basic-Shapes
::: (unit (import)
(display-shape (send factory make-union (export Shape Rectangle Circle Translated)
(send factory make-rectangle 10 30) (define Shape (interface :::)) ; see Figure 2
(send factory make-translated (define Rectangle (class* null (Shape) :: :))
(send factory make-circle 20) 30 30))) (define Circle (class* null (Shape) :: :))
(define Translated (class* null (Shape) :: :))))
Figure 6: Revised clients using Abstract Factory
Figure 7: Creating Units
interface, which describ es the extended shap e typ e for the
(define Gui
b ounding b ox classes just as Shap e describ es the typ e for
(unit (import Shape)
the original shap e classes.
(export display-shape)
The new display-shape client in Figure 5 uses b ounding
(define display-shape :: :))) ; see Figure 3
box information to center its shap e in a window. Unfortu-
nately,wemust also mo dify the clients so they create in-
(define Picture
stances of the new b ounding b ox classes instead of the origi-
(unit (import Rectangle Circle Translated display-shape)
nal shap e classes, includin g clients that do not use b ounding
(export)
(display-shape (make-object :::)))) ; see Figure 3
box information. Thus, the standard ob ject-oriented archi-
tecture do es not satisfy our original goal; it do es not supp ort
Figure 8: Unitized shap e clients
op eration extensions to the shap e datatyp e without mo di-
fying existing clients.
Since ob ject-oriented programming constructs do not ad-
dress this problem directly,wemust resort to a programming
4.1 Unitizing the Basic Shap es
proto col or pattern. In this case, the Abstract Factory pat-
tern [15] and a mutable reference solves the problem. The
A mo dule in MzScheme is called a unit . Figure 7 shows the
Abstract Factory pattern relies on one ob ject, called the fac-
basic shap e classes encapsulated in a Basic-Shapes unit.
tory , to create instances of the shap e classes. The factory
This unit imp orts nothing and exp orts all of the basic shap e
supplies one creation metho d for eachvariant of the shap e,
classes. The b o dy of the unit contains the class de nitions
and clients create shap es by calling these metho ds instead
exactly as they app ear in Figure 2.
of using make-object directly.Tochange the classes that are
In general, the shap e of a unit expression is
instantiated byclients, it is only necessary to change the
factory, whichisstoredinthemutable reference. A revised
(unit (import variable )
client, using the Abstract Factory,isshown in Figure 6.
(export variable )
The Abstract Factory pattern implements a simple dy-
unit-body-expr )
1
namic linker, where set! installs the link. It separates the
de nition of shap es and clients so that a sp eci c shap e im-
(centered ellipses indicate rep eated syntactic patterns). The
plementation can b e selected at a later time, rather than
unit-body-expr shave the same form as top-level Scheme ex-
hard-wiring a reference to a particular implementation into
pressions, allowing a mixture of expressions and de nitions,
the client. However, using a construct like set! for linking
but de ne within a unit expression creates a unit-lo cal vari-
obscures this intent b oth to other programmers and to the
able instead of a top-level variable. The unit's imp orted vari-
compiler. A more robust solution is to improve the mo dule
ables are b ound within the unit-body-expr s. Each exp orted
language.
variable must b e de ned by some unit-body-expr . Unex-
ported variables that are de ned in the unit-body-expr sare
private to the unit.
4 Better Reuse through Units and Mixins
Figure 8 de nes two client units of Basic-Shapes: Gui
and Picture. The Gui unit provides the function display-
In the previous section, we develop ed the Shap e datatyp e
shape (the same as in Figure 3). Since it only dep ends on
and its collection of op erations, and weshowed howobject-
the functionali tyintheShap e typ e, not the sp eci c variants,
oriented programming supp orts new variants and op erations
it only imp orts Shap e.ThePicture unit imp orts all of the
in separately develop ed extensions. In this section, wemake
shap e variants|so it can construct instances|as well as
the separate development explicit using MzScheme's mo d-
the display-shape function, and it exp orts nothing. When
ule system; the basic de nitions, the extensions, and the
Picture is invoked as part of a program, it constructs a
clients are all de ned in separate mo dules. MzScheme sup-
shap e and displays it.
p orts separate compilation for these mo dules, and provides
A unit is an unevaluated bundle of co de, much likea
a exible language for linking them. Indeed, the linking im-
\.o" ob ject le created by compiling a traditional language.
plemented with an Abstract Factory in the previous section
At the p oint where Basic-Shapes, Gui,and Picture are
can b e more naturally de ned through mo dule linking . Fi-
de ned as units, no shap e classes have b een de ned, no in-
nally,we showhow MzScheme's class-mo dule combination
stances have b een created, and no drawing window has b een
provides new opp ortunities for reuse that are not available
op ened. Each unit encapsulates its de nitions and expres-
in conventional ob ject-oriented languages.
sions without evaluating them until the unit is invoked, just
1
Factory Metho d is a related pattern where an extra op eration in
like a pro cedure encapsulates expressions until it is applied.
the datatyp e is used to create instances instead of a separate factory
However, none of the units in Figures 7 and 8 can b e invoked
ob ject. Factory Metho d applies to an interesting sp ecial case: the
directly b ecause each unit requires imp orts. The units must
datatyp e client and the datatyp e implementation are the same, thus
making the datatyp e implementation extensible.
rst b e linked together to form a program. 4
(define Basic-Program (define Union-Shape
(compound-unit (unit (import Shape)
(import) (export Union)
(link [S (Basic-Shapes)] (define Union (class* null (Shape) :: :)))) ; see Figure 4
[G (Gui (S Shape))]
[P (Picture (S Rectangle)(S Circle)(S Translated) (define Basic+Union-Shapes
(G display-shape))]) (compound-unit
(export))) (import)
(link [S (Basic-Shapes)]
(invoke-unit Basic-Program) [US (Union-Shape (S Shape))])
(export (S Shape)
(S Rectangle)
Figure 9: Linking basic shap e program
(S Circle)
(S Translated)
(US Union))))
4.2 Linking the Shap e and Client Units
Figure 10: Variant extension in a unit
Units are linked together with the comp ound-unit form.
Figure 9 shows how to link the units of the previous sub-
section into a complete program: Basic-Program. The
Picture unit's imp orts are not a priori asso ciated with
Toevaluate a comp ound-unit expression, the expr sin
the classes in Basic-Shapes. This asso ciation is estab-
the link clause are evaluated to determine the comp ound
lished only bythe comp ound-unit expression, and it is
unit's constituents. For each constituent, the number of
established only in the context of Basic-Program.The
variables it imp orts must match the number of linkspec s
Picture unit can b e reused with di erent Shap e classes in
provided; otherwise, an exception is raised. Each linkspec
2
other comp ound units.
is matched to an imp orted variable by p osition. Each con-
The comp ound-unit form links several units, called
stituentmust also exp ort the variables that are referenced
constituent units, into one new compound unit. The link-
by link and exp ort clauses using the constituent's tag .
ing pro cess matches imp orted variables in each constituent
Once a comp ound unit's constituents are linked, the com-
unit with either variables exp orted by other constituents, or
p ound unit is indistingu ish abl e from an atomic unit. Con-
variables imp orted into the comp ound unit. The comp ound
ceptually, linking creates a new unit by merging the inter-
unit can then re-exp ort some of the variables exp orted by
nal expressions and de nitions from all the constituent units.
the constituents. Thus, Basic-Program is a unit with im-
During this merge, variables are renamed as necessary to im-
p orts and exp orts, just like Basic-Shapes or Gui, and no
plement linking b etween constituents and to avoid name col-
evaluation of the unit b o dies has o ccurred. But, unlikethe
lisions b etween unrelated variables. The merged unit-body-
Basic-Shapes and Gui units, Basic-Program is a com-
expr s are ordered to match the order of the constituents in
3
plete program b ecause it has no imp orts.
the comp ound-unit's link clause.
Each comp ound-unit expression
4.3 Invoking Unit Programs
(compound-unit (import variable )
(link [tag (expr linkspec )]
1 1 1
The Basic-Program unit from Figure 9 is a complete pro-
.
gram, analogous to a conventional application , but the pro-
.
.
gram still has not b een executed. In most languages with
[tag (expr linkspec )])
n n n
mo dule systems, a complete program is executed through
(export (tag variable) ))
commands outside the language. In MzScheme, a program
unit is executed directly with the invoke-unit form:
has three parts:
The imp ort clause lists variables that are imp orted
(invoke-unit expr)
into the comp ound unit. These imp orted variables can
b e linked to the constituent unit's imp orts.
The value of expr must b e a unit. Invo cation evaluates
the unit's de nitions and expressions, and the result of the
The link clause sp eci es how the comp ound unit is cre-
last expression in the unit is the result of the invoke-unit
ated from the constituent units. Each constituentunit
expression. Hence, to run Basic-Program,evaluate
is sp eci ed via an expr and identi ed with a unique
tag .Following the expr , a link sp eci cation linkspec
(invoke-unit Basic-Program)
is provided for each of the constituent's imp orts. Link
sp eci cations havetwo forms:
4.4 New Units fora NewVariant
{ A linkspec of the form variable links the con-
stituent's imp ort to the corresp onding imp ort of
To extend Shap e with a Union variant, we de ne the exten-
the comp ound unit.
sion in its own unit, Union-Shape,asshown in Figure 10.
{ A linkspec of the form (tag variable) links the con-
2
In MzScheme's extended unit language with signatures, linking
stituent's imp ort to variable as exp orted bythe
matches variables by name rather than by p osition. When the number
tag constituent.
of imp orts is small, linking by p osition is simpler b ecause it avoids
complex machinery for renaming variables.
The exp ort clause re-exp orts variables from the com-
3
The implementation of linking is equivalent to this reduction,
p ound unit that are exp orted from the constituents.
but far more ecient. In particular, it is not necessary to extract
expressions from the constituent units, whichwould break separate
The tag indicates the constituent and variable is the
compilation.
variable exp orted by that constituent. 5
(define Union-Picture (define BB-Shapes
(unit (import Rectangle Circle Translated Union (unit (import Shape Rectangle Circle Translated Union)
display-shape) (export BB-Shape BB-Rectangle BB-Circle
(export) BB-Translated BB-Union BB)
(display-shape (make-object :::)))) ; see Figure 4 (define BB-Shape (interface (Shape) :::)) ; see Figure 5
(define BB-Rectangle (class* Rectangle :: :))
(define Union-Program (define BB-Circle (class* Circle :: :))
(compound-unit (define BB-Translated (class* Translated :: :))
(import) (define BB-Union (class* Union :::))
(link [S (Basic+Union-Shapes)] (define BB :::)))
[G (Gui (S Shape))]
[P (Picture (S Rectangle)(S Circle)(S Translated) (define Basic+Union+BB-Shapes
(G display-shape))] (compound-unit
[UP (Union-Picture (S Rectangle) (import)
(S Circle) (link [S (Basic+Union-Shapes)]
(S Translated) [BS (BB-Shapes (S Shape)
(S Union) (S Rectangle)
(G display-shape))]) (S Circle)
(export))) (S Translated)
(S Union))])
(invoke-unit Union-Program) (export (S Shape)
(BS BB-Shape)(BS BB)
; rename BS's BB-Rectangle to Rectangle, etc.:
Figure 11: New client and the extended program
(BS (BB-Rectangle Rectangle))
(BS (BB-Circle Circle))
(BS (BB-Translated Translated))
(BS (BB-Union Union)))))
The Shap e class is imp orted into Union-Shape, and the new
Union class is exp orted. In terms of Figure 1 (b), Union-
Figure 12: Op eration extension in a unit
Shape corresp onds to the smaller dashed b ox, drawn around
the new variant class. The solid b ox is the original unmo d-
i ed Basic-Shapes unit, and the outer dashed b ox in (b)
is Basic+Union-Shapes, a comp ound unit linking Union-
(define BB-Gui
Shape together with Basic-Shapes.
(unit (import BB-Shape BB)
Since the Basic+Union-Shapes unit exp orts the vari-
(export display-shape)
(define display-shape
ants de ned by b oth Basic-Shapes and Union-Shape,it
(lambda (shape)
can serve as a replacement for the original Basic-Shapes
(if (not (is-a? shape BB-Shape))
unit, yet it can also provide more functionality for new
:: :);see Figure 5
clients. The Union-Program unit in Figure 11 demon-
:::)))
strates b oth of these uses. In this new program, the Gui
and Picture clients are reused intact from the original pro-
(define BB-Program
gram, but they are now linked to Basic+Union-Shapes
(compound-unit
instead of Basic-Shapes. An additional client unit, Union-
(import)
Picture, takes advantage of the shap e extension to drawa
(link [S (Basic+Union+BB-Shapes)]
[BG (BB-Gui (S BB-Shape)(S BB))]
sup erimp osed rectangle and circle picture.
[P (Picture (S Rectangle)(S Circle)(S Translated)
(BG display-shape))]
4.5 New Units and Mixins for a New Op eration
[UP (Union-Picture (S Rectangle)(S Circle)
(S Translated)(S Union)
To extend Shap e with a bounding-box op eration, wede ne
(BG display-shape))])
the BB-Shapes unit in Figure 12. This unit corresp onds to
(export)))
the smaller dashed b ox in Figure 1 (c).
The BB-Shapes unit is the rst example to rely on mix-
(invoke-unit BB-Program)
ins. The BB-Rectangle class is derived from an imp orted
Rectangle class, which is not determined until the unit is
Figure 13: Program with the op eration extension
linked|lo ng after the unit is compiled. Thus, BB-Rectangle
de nes a mixin , a class extension that is parameterized over
its sup erclass.
The comp ound unit Basic+Union+BB-Shapes links As b efore, the Basic+Union+BB-Shapes unit serves
as a replacement for either Basic-Shapes or Basic+Union-
the Basic+Union-Shapes unit from the previous section
with the new b ounding-b ox unit, then exp orts the b ounding- Shapes, and also provides new functionality for new clients.
One new clientisBB-Gui (see Figure 13), whichprovides
box classes. As the b ounding-b ox classes are exp orted, they
4
are renamed to match the original class names, i.e., BB- a display-shape that exploits b ounding b ox information to
center a shap e in a window. The BB-Gui unit replaces Gui,
Rectangle is renamed to Rectangle, and so on. This renam-
ing do es not a ect the linking within Basic+Union+BB- but wereusePicture and Union-Picture without mo dify-
ing them. An Abstract Factory is unnecessary b ecause units
Shapes; it only a ects the waythatBasic+Union+BB-
Shapes is linked with other units. already p ermit us to vary the connection b etween the shap e-
creating clients and the instantiated classes. Putting every-
4
The simpli ed description of comp ound-unit in Section 4.2 did
thing together pro duces the new program BB-Program at
not cover the syntax for renaming exp orts. For a complete description
the b ottom of Figure 13.
of comp ound-unit, see the MzScheme manual [12]. 6
5 The Moral of the Story
(define Color-Shape
(unit (import Shape)
Wehave demonstrated how units and mixins apply to a
(export C-Shape)
sp eci c example, but a general principle is at work: sp ecify-
(define C-Shape
ing connections b etween mo dules or classes separately from
(class* Shape () args
their de nitions. This principle is the key to making units
(rename
and mixins succeed together without con ating the distinct
[super-draw draw])
(public
purp oses of mo dule and class systems.
[color \black"]
Amodulesystemserves twokey purp oses:
[change-color
(lambda (c)
Separate Development: A mo dule encapsulates a
(set! color c))]
set of de nitions, clearly delineating the interface b e-
[draw
tween the mo dule and the rest of the program. Each
(lambda (window x y)
mo dule can b e develop ed in isolation and distributed
(send window set-color color)
to clients in a compiled form.
(super-draw window x y))])
(sequence
Linking: Mo dules are linked together to form a pro-
(apply super-init args))))))
gram. Linking connects the de nitions in one mo dule
with those in another, but a mo dule cannot interfere
(define Basic+Union+BB+Color-Shapes
with the internal structure of any other mo dule.
(compound-unit
(import)
In contrast, a class system supp orts three di erentkey ser-
(link [S (Basic+Union+BB-Shapes)]
vices:
[CR (Color-Shape (S Rectangle))]
[CC (Color-Shape (S Circle))]
Extensible Typ es: An interface de nes an extensible
[CT (Color-Shape (S Translated))]
typ e, and a class implements suchatyp e.
[CU (Color-Shape (S Union))])
(export (S Shape)
SelectiveReuse: A class can selectively re ne the
(S BB-Shape)
implementation of its sup erclass, preserving some in-
(S BB)
herited de nitions and overriding others with its own
(CR (C-Shape Rectangle))
(CC (C-Shape Circle))
de nitions.
(CT (C-Shape Translated))
Instantiation: A class is instantiated to create an ob-
(CU (C-Shape Union)))))
ject, a rst-class value that encapsulates the metho ds
and instance variables of the class.
Figure 14: Reusing a class extension
Toserve their distinct purp oses, mo dules and classes re-
quire distinct constructs in a programming language, but
4.6 Synergy at Work these constructs interact. In our example program, the col-
lection of geometric shap es is naturally implemented as a set
The shap e example demonstrates the synergy of units and
of Shap e classes. The implementation of the shap e classes
mixins. Units, by separating the de nition and linking of
and the client co de that uses them are de ned in separate
mo dules, supp ort the reuse of Picture and Union-Picture
mo dules. Using classes to represent shap es makes it easy to
as the shap e representation evolves. Mixins, by abstracting
extend the shap e classes without mo difying the basic de -
a class expression over an imp orted class, enable the encap-
nition of a shap e. Separating the de nition of shap es from
sulation of each extension in its own unit. The combination
their use in di erent mo dules makes it easy to replace the
of units and mixins thus enables a direct translation of the
original shap e classes with new classes without mo difying
ideal program structure from Figure 1 into a working pro-
the client. This is precisely how mo dular ob ject-oriented
gram.
co de is supp osed to work.
Wehaveachieved the complete reuse of existing co de at
Unfortunately, the existing mo dule-class combinations
every stage in the extension of Shap e, but even more reuse
do not supp ort this sort of mo dular ob ject-oriented pro-
is p ossible. The co de in Figure 14 illustrates how units and
gramming. In Java, for example, if the Rectangle class is ex-
mixins combine to allow the use of one extension multiple
tended, then a client mo dule that creates Rectangle instances
times. The Color-Shape unit imp orts a Shap e class and
must b e mo di ed to refer to the new, extended class. The
extends it to handle colors. With this single unit containing
ro ot of this problem, b oth in Java and many other ob ject-
a single mixin, we can extend all four of the shap e variants:
oriented languages, is that the connections b etween mo d-
Rectangle, Circle, Translated, and Union. The comp ound unit
ules are hard-wired within the mo dules. For example, client
Basic+Union+BB+Color-Shapes in Figure 14 uses the
mo dules declare that they imp ort the shap e mo dule instead
Color-Shape unit four times to obtain the set of color
of imp orting a shap e mo dule.
shap e classes.
The design of mo dule and class constructs must encour-
The co de in Figure 14 uses a few features that are not
age the interaction of the constructs. The Shap e example
describ ed in this pap er (the rename clause in a class* ex-
suggests a lesson for the design of mo dules:
pression, and the use of args to stand for multiple argu-
ments, passed on to sup er-init with apply ). These details are
Separate a module's linking speci cationfrom its
covered in the MzScheme reference manual [12]. The p oint
encapsulated de nitions.
here is that units and mixins op en new avenues for reuse on
In other words, a mo dule should describ e its imp orts with
a large scale.
enough detail to supp ort separate compilation, but the mo d-
ule should not sp ecify the source of its imp orts. Instead, the 7
imp orts should b e supplied externally by a linking expres- bindings, whichprovides a theoretical foundation for im-
sion. plementing b oth mo dules and classes. Similarl y, Jagan-
A mo dule system with external linking in turn constrains nathan [21] and Miller and Rozas [29] prop osed rst-class
the design of the class system. A mo dule may encapsulate environments as a common mechanism. Bracha [3] has ex-
a class de nition with an imp orted sup erclass (e.g., BB- plored mixins for b oth mo dular and ob ject-oriented pro-
Rectangle in Figure 12). Since mo dule linking is sp eci ed gramming; Ancona and Zucca [1]provide a categorical treat-
outside the mo dule, the sup erclass is not determined until ment of this view. Our work is complementary to all of the
the mo dule is linked, so the class expression is de facto pa- ab ovework, b ecause we fo cus on designing the constructs
rameterized over its sup erclass. Such a parameterized class to b e used by a programmer, rather than the metho d used
is a mixin . Mixins tend to b e computational ly more exp en- to implement those constructs.
sive than classes, but the cost is small [14]. In parallel to Languages that have promoted mo dularizatio n, includ-
the lesson for mo dules, the requirement to supp ort mixins ing Mesa [31], Mo dula-2 [45], and SML [30], provide no di-
can b e stated as follows: rect supp ort for ob ject-oriented programming. Similarl y,
early ob ject-oriented languages, suchasSimula 67 [9] and
Separate a class's superclass speci cation from its
Smalltalk [16], provide no mo dule system. In contrast, lan-
extending de nitions.
guages such as Ada 95 [20], Common Lisp [42], Dylan [41],
Haskell [19], Java [17], and Mo dula-3 [18] provide b oth mo d-
Mixins are valuable in their own right. While classes enable
ules and classes. For Cecil [4], Chambers and Leavens [5] de-
reuse b ecause each class can b e extended and re ned by
signed a mo dule system sp eci cally to complement a class
de ning new sub classes, the reuse is one-sided: each class
system with multi-metho ds. Unfortunately, these mo dule
can b e extended in many di erentways, but each extension
and class systems do not supp ort external connections|a
applies only to its sup erclass. A mixin is parameterized
central principle of our design that is crucial to software
with resp ect to its sup erclass, so it can add functionalityto
engineering (see Section 5).
many di erent classes. Thus, the reuse p otential of a mixin
Scheme [6]provides no sp eci c mechanisms for mo dular
is greater than that of a class.
or ob ject-oriented programming. Instead, Scheme supp orts
mo dular programming through lexical scop e, and many im-
6 ATyp e Challenge
plementations provide separate compilation for top-level ex-
pressions. Programmers can regard top-level expressions as
Wehave explored typ ed mo dels of mixins [14] and units [13]
\mo dules" that hide private de nitions by using let or le-
separately in previous work. In addition, wehaveantici-
trec.Anumber of Scheme systems have b een develop ed
pated an extension of the presentwork with typ es byin-
that co dify the mo dule-via-top-le vel idea [8, 10 , 36, 35, 44],
cluding is-a? safety tests in our examples, and byshowing
but none of these satis es the criteria in Section 5. In con-
how the Shap e and BB-Shap e interfaces are linked to clients
trast, Kelsey's prop osed mo dule system [22] captures many
to enable those tests. Still, certain challenges remain for
of the same ideas as units. Scheme can also supp ort ob ject-
bringing mixins and units together in a single typ ed mo del.
oriented programming by simulating ob jects with pro ce-
For mixins, the previously published typ e rules assume a
dures and classes with higher-order pro cedures [37]. Sev-
complete program and a single namespace for mixin names.
eral ob ject-oriented extensions for Scheme have b een devel-
5
For units, the previously published language do es not ex-
op ed [2, 34], including some that supp ort mixins [25, 33 ].
press the kind of typ e relationshi ps necessary for imp orting
However, none of these systems provide complete languages
and exp orting interface typ es (e.g., imp orting typ es A and
for b oth mo dular and ob ject-oriented programming.
B where A must b e a subtyp e of B).
Others have explored a similar combination of classes and
8 Conclusion
mo dules in a typ ed setting. The mo dule systems in Ob jec-
tive Caml [28, 38 ] and OML [39] supp ort externally sp eci ed
Units and mixins promote a synergistic integration of mo du-
connections, and since a class can b e de ned within a mo d-
lar and ob ject-oriented programming techniques. The com-
ule, these languages also provide a form of mixins. However,
bination succeeds due to a consistent separation of de ni-
the mo dules and mixins in these languages fail to supp ort
tions (encapsulated in mo dules or classes) from connections
the synergy wehave demonstrated for units and mixins. In
(b etween mo dules or classes) in b oth units and mixins.
particular, they do not allow the op eration extension demon-
The bulk of the pap er explores the extensibili ty problem
strated in Section 4 b ecause an imp orted class must match
b ecause it highlights many of the advantages of units and
the exp ected typ e exactly|no extra metho ds are allowed.
mixins. Strictly sp eaking, the problem can b e solved using
In our example, Picture is initiall y linked to the Rectangle
conventional mo dule and class systems and the Abstract
class and later linked to BB-Rectangle; since the latter has
Factory pattern. Nevertheless, a straightforward datatyp e
more metho ds, neither Ob jective CamlnorOMLwould al-
implementation using units and mixins is more immediately
low Picture to b e reused in this way. Our example thus
extensible. This natural bias towards reuse and extension is
suggests a third lesson for the design of mo dule and class
the essential b ene t of units and mixins.
typ e systems:
Al low subsumption for connections, including both
For a complete version of the co de presented here, see
module linking and class extension.
www.cs.rice.edu/CS/PLT/Publications/#ifcp98-ff
5
7 Related Work
Queinnec's [33] system actually provides generic function exten-
sions that are parameterized over a generic function, rather than
parameterized class extensions. While the system do es not provide
Much of the previous research on mo dules and classes fo-
mixins per se ,itfollows the principle of separating connections from
cused on unifying the constructs. Lee and Friedman [26, 27 ]
de nitions.
investigated languages that work directly on variables and 8
Acknowledgements [16] Goldb erg, A. and D. Robson. Smal ltalk 80: The Lan-
guage. Addison-Wesley, Reading, 1989.
The authors would like to thank Matthias Felleisen, Corky
[17] Gosling, J., B. Joy and G. Steele. The Java Language
Cartwright, John Clements, Dan Friedman, Shriram Krish-
Speci cation. The Java Series. Addison-Wesley, Read-
namurthi, Paul Steckler, and the anonymous reviewers.
ing, MA, USA, June 1996.
References
[18] Harbison, S. P. Modula-3. Prentice Hall, 1991.
[19] Hudak, P.andWadler, P. (Eds.). Rep ort on the
[1] Ancona, D. and E. Zucca. An algebraic approach
programming language Haskell. Technical Rep ort
to mixins and mo dularity. In Hanus, M. and
YALE/DCS/RR777, Yale University, Departmentof
M. Ro drguez-Artalejo, editors, Proc. Conferenceon
Computer Science, August 1991.
Algebraic and Logic Programming, Lecture Notes in
Computer Science 1139, pages 179{193, Berlin, 1996.
[20] International Organization for Standardizatio n. Ada
Springer Verlag.
95 Reference Manual. The Language. The Standard Li-
braries,Janurary 1995.
[2] Bartley, D. H. and J. C. Jensen. The implementation
of PC Scheme. In Proc. ACM Conference on Lisp and
[21] Jagannathan, S. Metalevel buildin g blo cks for mo du-
Functional Programming, pages 86{93, 1986.
lar systems. ACM Transactions on Programming Lan-
guages and Systems, 16(3):456{492, May 1994.
[3] Bracha, G. The Programming Language Jigsaw: Mix-
ins, Modularity and Multiple Inheritance. Ph.D. thesis,
[22] Kelsey,R.A.Fully-parameterized mo dules or the miss-
Dept. of Computer Science, University of Utah, March
ing link. Technical Rep ort 97-3, NEC Research Insti-
1992.
tute, 1997.
[4] Chamb ers, C. The Cecil Language Speci cation and
[23] Krishnamurthi, S., M. Felleisen and D. Friedman. Syn-
Rationale: Version 2.0, 1995.
thesizing ob ject-oriented and functional design to pro-
mote re-use. In Proc. European Conference on Object-
[5] Chamb ers, C. and G. T. Leavens. Typ echecking and
OrientedProgramming, 1998.
mo dules for multi-metho ds. ACM Transactions on
Programming Languages and Systems, 17(6):805{843,
[24] Kuhne, T. The translator pattern|external function-
November 1995.
ality with homomorphic mappings. In Proceedings of
4
TOOLS 23, USA, pages 48{62, July 1997.
[6] Clinger, W. and Rees, J. (Eds.). The revised rep ort on
the algorithmic language Scheme. ACM Lisp Pointers,
[25] Lang, K. J. and B. A. Pearlmutter. Oaklisp: an ob ject-
4(3), July 1991.
oriented dialect of Scheme. Lisp and Symbolic Com-
putation: An International Journal, 1(1):39{51, May
[7] Co ok, W. R. Ob ject-oriented programming versus ab-
1988.
stract data typ es. In Foundations of Object-Oriented
Languages, pages 151{178, June 1990.
[26] Lee, S.-D. and D. P.Friedman. Quasi-static scoping:
Sharing variable bindings across multiple lexical scop es.
[8] Curtis, P. and J. Rauen. A mo dule system for Scheme.
In Proc. ACM Symposium on Principles of Program-
In Proc. ACM Conference on Lisp and Functional Pro-
ming Languages, pages 479{492, 1993.
gramming, pages 13{28, 1990.
[27] Lee, S.-D. and D. P.Friedman. Enriching the lambda
[9] Dahl, O.-J., B. Myrhaug and K. Nygaard. SIMULA 67.
calculus with context toward a theory of incremental
common base language. Technical Rep ort Publ. No. S-
program construction. In Proc. ACM International
2, Norwegian Computing Center, Oslo, Norway,May
ConferenceonFunctional Programming, pages 239{
1968.
250, 1996.
[10] Feeley,M. Gambit-C, a portable Scheme implementa-
[28] Leroy,X. The Objective Caml system,1996. URL:
tion, 1996.
http://pauillac.inria.fr/ocaml/.
[11] Felleisen, M. and D. P.Friedman. A Little Java, A Few
[29] Miller, J. and G. Rozas. Free variables and rst-class
Patterns. The MIT Press, 1998.
environments. Lisp and Symbolic Computation: An In-
ternational Journal, 3(4):107{141, 1991.
[12] Flatt, M. PLT MzScheme: Language manual. Technical
Rep ort TR97-280, Rice University, 1997.
[30] Milner, R., M. Tofte and R. Harp er. The De nition
of StandardML. The MIT Press, Cambridge, Mas-
[13] Flatt, M. and M. Felleisen. Units: Co ol mo dules for
sachusetts and London, England, 1990.
HOT languages. In Proc. ACM ConferenceonPro-
gramming Language Design and Implementation, pages
[31] Mitchell, J. G., W. Mayb erry and R. Sweet. Mesa Lan-
236{248, 1998.
guage Manual, 1979.
[14] Flatt, M., S. Krishnamurthi and M. Felleisen. Classes
[32] Palsb erg, J. and C. B. Jay. The essence of the Visitor
and mixins. In Proc. ACM Symposium on Principles of
pattern. Technical Rep ort 05, UniversityofTechnology,
Programming Languages, pages 171{183, 1998.
Sydney, 1997.
[15] Gamma, E., R. Helm, R. Johnson and J. Vlissides. De-
[33] Queinnec, C. Distributed generic functions. In Proc.
sign Patterns: Elements of Reusable Object-Oriented
1997 France-Japan Workshop on Object-BasedParal lel
Software. Addison Wesley, Massachusetts, 1994.
and Distributed Computing, 1997. 9
[34] Queinnec, C. Meroon V3: A Smal l, Ecient, and En- App endix: MzScheme Class and Interface Syntax
hanced Object System, 1997.
Classes
[35] Queinnec, C. and D. De Roure. Sharing co de through
The shap e of a MzScheme class declaration is:
rst-class envinroments. In Proc. ACM International
ConferenceonFunctional Programming, pages 251{
(class*
261, 1996.
superclass-expr (interface-expr )(init-variable )
instance-variable-clause )
[36] Rees, J. Another mo dule system for Scheme, 1994.
Scheme48 do cumentation.
(centered ellipses indicate rep eated patterns). The expres-
sion superclass-expr determines the sup erclass for the new
[37] Rees, J. and N. Adams. Ob ject-oriented programming
class, and the interface-expr s sp ecify the interfaces imple-
in Scheme. In Proc. ACM ConferenceonLispand
mented by the class. The init-variable s receive instance-
Functional Programming, pages 277{288, 1988.
sp eci c initiali zatio n values when the class is instantiated
(like the arguments supplied with new in Java). Finally, the
[38] Remy, D. and J. Vouillon. Ob jective ML: A simple
instance-variable-clause s de ne the instance variables of the
ob ject-oriented extension of ML. In Proc. ACM Sym-
class, plus expressions to b e evaluated for each instance. For
posium on Principles of Programming Languages, pages
example, a public clause declares public instance variables
40{53, Paris, France, 15{17 Janurary 1997.
and metho ds.
[39] Reppy, J. and J. Riecke. Simple ob jects for Stan-
Thus, the de nition
dard ML. In Proc. ACM ConferenceonProgramming
(define Rectangle
Language Design and Implementation, pages 171{180,
(class* null (Shape)(width height)
1996.
(public
[draw (lambda (window x y) )])))
[40] Reynolds, J. C. User-de ned typ es and pro cedural data
structures as complementary approachestodataab-
intro duces the base class Rectangle.Thenull indicates that
straction. In Schuman, S. A., editor, New Directions in
Rectangle is not derived from any class, (Shap e) indicates
Algorithmic Languages, pages 157{168. IFIP Working
that it implements the Shap e interface, and (width height)
Group 2.1 on Algol, 1975.
indicates that two initial izati on arguments are consumed
for initial izi ng an instance. There is one instance-variable-
[41] Shalit, A. The Dylan Reference Manual. Addison-
clause that de nes a public metho d: draw .
Wesley, 1996.
MzScheme's ob ject system do es not distinguish b etween
instance variables and metho ds. Instead, pro cedure-valued
[42] Steele Jr., G. L. Common Lisp: The Language. Digital
instance variables act like metho ds. The draw declaration in
Press, second edition, 1990.
Rectangle de nes an instance variable, and (lambda (win-
[43] Szyp erski, C. A. Imp ort is not inheritance { whywe
dow x y) :::) is its initial value expression, evaluated once
need b oth: Mo dules and classes. In European Con-
p er instance. When draw is called as the metho d of some
ference on Object-OrientedProgramming,volume 615
ob ject, draw may refer to the ob ject via this . In most ob ject-
of Lecture Notes in Computer Science, pages 19{32.
oriented languages, this is passed in as an implicit argument
Springer-Verlag, New York, N.Y., 1992.
to a metho d; in MzScheme, this is part of the environment
for evaluating initiali zati on expression, so each \metho d" in
[44] Tung, S.-H. Interactive mo dular programming in
6
an ob ject is a closure containing the correct value of this .
Scheme. In Proc. ACM Conference on Lisp and Func-
An instance of Rectangle is created using the make-object
tional Programming, pages 86{95, 1992.
primitive. Along with the class to instantiate, make-object
takes any initializ atio n arguments that are exp ected for the
[45] Wirth, N. Programming in Modula-2. Springer-Verlag,
class. In the case of Rectangle,two initiali zati on arguments
1983.
sp ecify the size of the shap e:
(define rect (make-object Rectangle 50 100))
The value of an instance variable is extracted from an ob-
ject using ivar. The following expression calls the draw
\metho d" of rect by extracting the value of draw and ap-
plying it as a pro cedure:
((ivar rect draw) window 00)
Since metho d calls of this form are common, MzScheme pro-
vides a send macro. The following send expression is equiv-
alent to the ab ove ivar expression:
(send rect draw window 00)
6
MzScheme's approach to metho ds avoids duplicating the func-
tionality of pro cedures with metho ds. However, this design incurs
a substantial cost in practice b ecause each ob ject record must pro-
vide a slot for every metho d in the class, and a closure is created for
each metho d p er ob ject. Adding true metho ds to the ob ject system,
like metho ds in most ob ject-oriented languages, would improvethe
run-time p erformance of the ob ject system and would not a ect the
essence of our presentation. 10
Interfaces
An interface is declared in MzScheme using the interface
form:
(interface (superinterface-expr )
variable )
The superinterface-expr s sp ecify all of the sup erinterfaces
for the new interface, and the variable s are the instance
variables required by the interface (in addition to variables
declared by the sup erinterfaces). For example, the de nition
(define Shape (interface () draw))
creates an interface named Shap e with one variable: draw .
Every class that implements Shap e must declare a draw in-
stance variable. The de nition
(define BB-Shape (interface (Shape) bounding-box))
creates an interface named BB-Shap e with twovariables:
draw and bounding-box .SinceShap e is the sup erinterface
of BB-Shap e,every class that implements BB-Shap e also im-
plements Shap e.
A class implements an interface only when it sp eci cally
declares the implementation (as in Java). Thus, the Rectan-
gle class in the previous section only implements the Shap e
interface.
Derived Classes
The de nition
(define BB-Rectangle
(class* Rectangle (BB-Shape)(width height)
(public [bounding-box ])
(sequence (super-init width height))))
derives a BB-Rectangle class that implements BB-Shap e.The
draw metho d, required to implement BB-Shap e, is inherited
from Rectangle.
The BB-Rectangle class declares the new bounding-box
metho d. It also includes a sequence clause that calls sup er-
init.Asequence clause declares expressions to b e evaluated
for each instance. It is commonly used to call the sp ecial
sup er-init pro cedure, which initializes the part of the instance
de ned by the sup erclass (like calling sup er in a Javacon-
structor); a derived class must call sup er-init exactly once for
every instance. In the case of BB-Rectangle, calling sup er-
init p erforms Rectangle's initiali zatio n for the instance. BB-
Rectangle provides two arguments to sup er-init b ecause the
Rectangle class consumes two initiali zati on arguments. 11