The Artima Developer Community
Sponsored Link

Computing Thoughts
Mixins: Something Else You Can't Do With Java Generics?
by Bruce Eckel
October 19, 2005
The paper "A First-Class Approach to Genericity" introduces the idea of the mixin, which seems to be quite a powerful concept, and then shows that you can't do it with Java generics. I wonder if anyone has any alternative approaches to this problem.


Here's the link to the paper (PDF).

(Also see the follow-on to this article, Mixins 2.

The term mixin seems to have acquired numerous meanings over time, but the fundamental concept is that of mixing in capabilities in the same way that you would mix adornments like cookies and candy pieces into ice cream. Although these things are reasonably well-blended, you can still see evidence of their having been mixed in. More importantly, it's something you do at the last minute, which makes it convenient to easily assemble classes.

One value for mixins is that they consistently apply characteristics and behaviors across multiple classes.

When you look at the way that it is used, the concept of a mixin seems very closely related to the Decorator design pattern. Something is decoratable, and you layer on functionality by wrapping other classes around the decoratable. Decorators, however, are implemented using composition and formal structures (the decoratable/decorator hierarchy), whereas mixins are inheritance-based. So you could think of parameterized-type-based mixins as a generic decorator mechanism that does not require the inheritance structure of the Decorator design pattern.

Because the resulting class contains all the methods of interest just like any other class, the mixin approach is arguably more natural than a decorator, because the type of the object that results from using decorators is the last type that it was decorated with, whereas the type of the mixin is all the types that have been mixed together.

One of the strongest arguments made for multiple inheritance in C++ is for the use of mixins. However, a more interesting and elegant approach to mixins is using parameterized types, whereby a mixin is a class that inherits from its type parameter. In C++, you can easily create mixins because C++ remembers the type of its template parameters.

Here's a C++ example with two mixin types: one that allows you to mix in the property of having a time stamp, and another that mixes in a serial number for each object instance:

//: generics/Mixins.cpp
#include <string>
#include <ctime>
#include <iostream>
using namespace std;

template<class T> class TimeStamped : public T {
  long timeStamp;
  TimeStamped() { timeStamp = time(0); }
  long getStamp() { return timeStamp; }

template<class T> class SerialNumbered : public T {
  long serialNumber;
  static long counter;
  SerialNumbered() { serialNumber = counter++; }
  long getSerialNumber() { return serialNumber; }

// Define and initialize the static storage:
template<class T> long SerialNumbered<T>::counter = 1;

int main() {
  TimeStamped<SerialNumbered<string> > mixin1, mixin2;
  mixin1.append("test string 1"); // A string method
  mixin2.append("test string 2");
  cout << mixin1 << " " << mixin1.getStamp() << " " <<
    mixin1.getSerialNumber() << endl;
  cout << mixin2 << " " << mixin2.getStamp() << " " <<
    mixin2.getSerialNumber() << endl;
} /* Output: (Sample)
test string 1 1129775318 1
test string 2 1129775318 2

Notice that the resulting type has all the methods of the mixed-in types. You can think of a mixin as a function that maps existing classes to new subclasses.

Unfortunately, Java generics don't permit this. Erasure forgets the base-class type, so a generic class cannot inherit from one of its generic parameters.

//: generics/
// {CompileTimeError}
import java.util.*;

// Can't inherit from a generic parameter:
public class TimeStamped<T> extends T {
  public final long timeStamp;
  TimeStamped() {
    timeStamp = new Date().getTime();

public class SerialNumbered<T> extends T {
  private static long counter = 1;
  public final long serialNumber = counter++;

public class Mixins {
  public static void main(String[] args) {
    SerialNumbered<TimeStamped<String>> mixin = 
      new SerialNumbered<TimeStamped<String>>();
} ///:~

So here's the question: is there some other way to perform something that produces this kind of mixin cleverness, or has erasure again foiled us?

Talk Back!


RSS Feed


About the Blogger



Sponsored Links

