is Missing multiple inheritance in sqeak a drawback ?

David Griswold David.Griswold at acm.org
Sat Oct 12 19:59:23 UTC 2002


Gilad Bracha's mixin concept, implemented in Strongtalk, are an
excellent, simple, elegant way of getting the advantages of MI without
the complexity.  It also provides a simple form of the kind of
combination algebra that Alan Kay mentioned, so that it is always clear
how the methods are combined. Of course, in Strongtalk, they are coupled
with the type system as well, but they would work just as well (and
maybe even better) in an untyped system like Squeak.

Here is a link to our paper with a complete description of the semantic
model:
	http://www.cs.ucsb.edu/projects/strongtalk/big/mixins-paper.ps

In fact, this should be very easy to add to Squeak, and would not even
require adding a separate mixin browser or anything, or any changes to
the VM (some new dependency tracking is needed in the reflective
interface, and in class name printing code).

This mixin model is much different and simpler than the complicated
mixins of the Lisp world.  It fits really well into a class-based,
single-inheritance language like Smalltalk- you don't even need to add
an explicit way of defining a mixin.  Basically, the idea is incredibly
simple: you can just add a new message, #mixin, that classes support.
Sending such a message to a class returns a mixin, which is basically
just the class with the superclass factored out as a parameter, so the
mixin is a kind of 'function' that is called with any superclass you
want.  To use the mixin, you simply 'invoke' it like a function on
another class that acts as the new superclass.  This instantiates a new
anonymous class (which the system canonicalizes), which is just like the
original class you got the mixin from, except that it has the class you
invoked the mixin on as its superclass.    The result is still a single
inheritance hierarchy, and abides perfectly by all the normal Smalltalk
language rules. (the one complication I've brushed over is that when
asking for the mixin you need to decide *which* superclass you want to
be the parameter; in Strongtalk we provided two messages, #mixin which
factors out Object (so you get all the methods up to Object in the
mixin), or #delta, which factors out only the immediate superclass of
the class).

A good example I always use from Smalltalk is that Strings really should
be Magnitudes, because all the relational operators #< etc. apply to
them, and subclasses of Magnitude can just define #< and get all the
other operators for free.  But because Strings inherit from Collections,
they can't also inherit from Magnitude, so in normal Smalltalks, all the
relational methods have to be reimplemented in String.

Using mixins, this problem is easy to solve.  Right now in Squeak,
String's superclass is ArrayedCollection.  Basically, you want to
'mixin' Magnitude in between ArrayedCollection and String.  You do that
by asking Magnitude for its mixin, then invoking that on
ArrayedCollection, which produces a new class that is just like
Magnitude except that it has ArrayedCollection as its superclass instead
of Object.  You just use that class as String's superclass.  Behind the
scenes, Squeak could avoid VM mixin support by simply copying the
methods and instance and class var definitions for each mixin
invocation, and keeping track of them so that they can be kept up to
date after reflective changes to the originating class.  To the VM, it
just looks like a regular single-inheritance hierarchy.

In the code, this would look like this:  If the mixin invokation
operator is #|>, then the definition of String goes from looking like
this

	ArrayedCollection
		variableByteSubclass: #String
		instanceVariableNames: ''
		classVariableNames: '...'
		poolDictionaries: ''
		category: 'Collections-Text'

to this, using mixins

	(Magnitude mixin |> ArrayedCollection)
		variableByteSubclass: #String
		instanceVariableNames: ''
		classVariableNames: '...'
		poolDictionaries: ''
		category: 'Collections-Text'

If you turned the mixin invokation operator around, it might look more
natural:

	(ArrayedCollection <| Magnitude mixin)
		variableByteSubclass: #String
		instanceVariableNames: ''
		classVariableNames: '...'
		poolDictionaries: ''
		category: 'Collections-Text'

That's all there is to it!  You define mixins as normal classes, and
just add three new messages to the system, #mixin, #delta, and #|>.

An even more useful and common example is being able to inherit the
Collection methods in any class you want, even if it can't inherit
directly from Collection, simply by mixing-in Collection on your
superclass and then just defining #do: (although this is currently
uglified by the fact that Squeak's Collection implements all those
'optional' methods that not all Collection's support, like #add: etc).

If anyone is interested in adding mixins to Squeak, I can help explain
what would have to be done.  It's not that hard!

Cheers,
-Dave

___________________________________________
"I believe in an open mind, but not so open that your brains fall
out." - Arthur Hays Sulzberger





More information about the Squeak-dev mailing list