Mixin-methods in Agora
Wolfgang De Meuter
Last revision: December 20th, 1997
Mixin-methods in Agora
Since prototype-based object-oriented programming languages feature no
classes, their inheritance mechanism must be defined directly on objects.
So usually, prototype-based languages allow an object to be extended
dynamically using some sort of extend operator, which allows an
object to be extended with new attributes.
However, such an operator can easily be used to breach the encapsulation of objects. This is due to the
plethora of operations in the mop
of languages that feature such an operator.
Agora shows that even in the absence of such extension operators (see the
very simple mop), inheritance is possible. The key idea is that
inheritance is accomplished by a special kind of methods that reside
inside the object. Such methods are called mixin-methods. Their contents
is added to the object upon invocation of the method.
The following example is written in Agora96. It defines a point that can
be extended by sending it the message becomeCircle. When the
point receives the message, the attribute listed in the mixin-method will
be added to the object:
point variable
{ x variable:0;
y variable:0;
becomeCircle mixin method:
[ r variable:0 ]
}
Mixin-methods can be declared functional (functional mixin
method:) or imperative (imperative mixin
method:). Functional mixin-methods return a view on the receiving
object. Imperative mixin-methods destructively change the receiving object.
Note: In Agora98, functional mixin-methods are called views.
Imperative mixin-methods were renamed mixins. The reason is that the
functional vs. imperative nomenclature induced a lot of confusion about
Agora's semantics.
The above example immediately raises the question whether it is possible
to extend an object 'from the outside' because mixin-methods cannot be
added to an object after it has been created (unless of course there is
another mixin-method that defines the former). In the language manual of
Agora96, we show that it is relatively easy to extend an object from the
outside, using the reflective facilities of Agora. The idea is to quote
some code and offer it to an object by a message. The object can then
evaluate this code object in its own context. But of course, when such an
'evaluating message' is not implemented, it is impossible to extend an
object from the outside. This very much resembles the subclass:
message of Smalltalk.