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.