The Artima Developer Community
Sponsored Link

Weblogs Forum
Mixins: Something Else You Can't Do With Java Generics?

27 replies on 2 pages. Most recent reply: Jan 2, 2006 9:30 PM by Matt O'Connor

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 27 replies on 2 pages [ 1 2 | » ]
Bruce Eckel

Posts: 875
Nickname: beckel
Registered: Jun, 2003

Mixins: Something Else You Can't Do With Java Generics? (View in Weblogs)
Posted: Oct 19, 2005 8:04 PM
Reply to this message Reply
Summary
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.
Advertisement

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;
public:
  TimeStamped() { timeStamp = time(0); }
  long getStamp() { return timeStamp; }
};

template<class T> class SerialNumbered : public T {
  long serialNumber;
  static long counter;
public:
  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/Mixins.java
// {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?


Bob Lee

Posts: 4
Nickname: crazybob
Registered: Oct, 2005

Re: Mixins: Something Else You Can't Do With Java Generics? Posted: Oct 19, 2005 9:42 PM
Reply to this message Reply
Bruce, you should check out Dynaop, http://dynaop.dev.java.net/. I'm ramping up to better support JDK 1.5 (i.e. I need to generify the API).

Christian Theune

Posts: 3
Nickname: theuni
Registered: Feb, 2005

Re: Mixins: Something Else You Can't Do With Java Generics? Posted: Oct 20, 2005 12:11 AM
Reply to this message Reply
Hmm. I don't want to rant here, but in the Zope world, (Zope 2 that is) we relied on the "Mixin" pattern a lot. A couple of years later we found out that it's not that convenient if you do it all around the place...

Just my 0.02$.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Mixins: Something Else You Can't Do With Java Generics? Posted: Oct 20, 2005 6:56 AM
Reply to this message Reply
This is the first time I've heard that called a "mixin." It's the 'Curiously Recurring Template Pattern.'

Jim Coplien wrote it up years ago.

Zane Rocknbaugh

Posts: 1
Nickname: zanerock
Registered: Dec, 2004

Re: Mixins: Something Else You Can't Do With Java Generics? Posted: Oct 20, 2005 7:50 AM
Reply to this message Reply
One can use inner classes to fake out mixins in Java. It takes more code than a true mixin would, but it's the best solution I've seen (and also solves 99.9% of the problems where one *really* does want multiple inheritance).

Let's assume primary class C, abstract mixin class M, and mixin interface I. M implements I and declares abstract protected methods to access data from the classes it is to be mixed into. So, to mix M into C, declare C to implement I and create anonymous inner class, AM, extending M and implementing the protected methods. Then in C, delegate functionality to implement I to AM.

I found this pattern somewhat fuzzily described at:
http://jonaquino.blogspot.com/2005/07/java-mixin-pattern-or-faking-multiple.html

Bruce Eckel

Posts: 875
Nickname: beckel
Registered: Jun, 2003

Re: Mixins: Something Else You Can't Do With Java Generics? Posted: Oct 20, 2005 8:24 AM
Reply to this message Reply
> This is the first time I've heard that called a "mixin."
> It's the 'Curiously Recurring Template Pattern.'
>
> Jim Coplien wrote it up years ago.

No, that's different. In CRTP, a new class inherits from a template instantiation that takes the new class as a parameter, like this (from Thinking in C++ Volume 2):

class CountedClass : public Counted<CountedClass> {};
class CountedClass2 : public Counted<CountedClass2> {};

Also see:
http://c2.com/cgi/wiki?CuriouslyRecurringTemplate

The CRTP is more like the Template Method pattern, whereas mixins are a more elegant form of a Decorator.

From the paper I cited in the article: "Nearly 20 years ago, the Lisp object-oriented community invented the term mixin to describe a class with a parametric parent..."

Kirby Files

Posts: 6
Nickname: ksfiles
Registered: Oct, 2005

Re: Mixins: Something Else You Can't Do With Java Generics? Posted: Oct 20, 2005 9:24 AM
Reply to this message Reply
I think your complaint is the main argument in favor of Aspect Oriented Programming (AOP). With AOP, you'd be able to do exactly what you want, namely apply methods from various sources to a composite class.

It wouldn't be inheritance-based, as you desire, but it would share the characteristics of the mixin example you give. AOP has the added advantage of being able be apply methods (or aspects) declaratively (via XML or annotations).

Of course, since all AOP implementations are currently post-processing driven, they have a certain manageability problem (PITA debugging, restrictions on execution environment, etc.) and a generally kludgy feel.

--kirby

Berin Loritsch

Posts: 5
Nickname: bloritsch
Registered: Jun, 2005

Re: Mixins: Something Else You Can't Do With Java Generics? Posted: Oct 20, 2005 10:03 AM
Reply to this message Reply
The only other alternative here is the dynamic proxy. Once you have an interface including all the interfaces of the mixins you want to include, the implementations are delegated to by the invocation interface. Also quite kludgy and generally alot more work than is normally necessary.

Aspects are a much better way of defining mixins in the Java world, but as someon else already mentioned they also have their drawbacks.

There is no nice, neat method to do mixins in Java.

Todd Blanchard

Posts: 316
Nickname: tblanchard
Registered: May, 2003

Java needs Traits Posted: Oct 20, 2005 11:49 AM
Reply to this message Reply
Traits are a construct that was originally implemented in Smalltalk, but other languages are beginning to adopt them. From the Traits paper http://www.iam.unibe.ch/~scg/Archive/Papers/Scha03aTraits.pdf

# Traits have the following properties. A trait provides a set of methods that implement behaviour.
# A trait requires a set of methods that serve as parameters for the provided behaviour.
# Traits do not specify any state variables, and the methods provided by traits never access state variables directly.
# Classes and traits can be composed from other traits, but the composition order is irrelevant. Conflicting methods must be explicitly resolved.
# Trait composition does not affect the semantics of a class: the meaning of the class is the same as it would be if all of the methods obtained from the trait(s) were defined directly in the class.
# Similarly, trait composition does not affect the semantics of a trait: a composite trait is equivalent to a flattened trait containing the same methods.

This gives something like mixins but simpler and still about as useful. Probably the most annoying thing about Java is the inability to add implementation to interfaces that could be generic. It results in duplication of code.

Traits would eliminate that.

Paul de Vrieze

Posts: 9
Nickname: pauldv
Registered: Oct, 2005

Re: Mixins: Something Else You Can't Do With Java Generics? Posted: Oct 21, 2005 4:48 AM
Reply to this message Reply
I find the concept of mixins to be a design flaw. The problems with mixins (as stated in the cited article) are that you are combining two types that do not know of eachother. The effect is similar to that of multiple inheritance, but without the explicit relation multiple inheritance implies.

Multiple inheritence of course also has it's share of problems, but one can make the language such that it fails on encountering them, or requiring explicit resolves. Mixin's introduce unexpected behaviour on unsuspecting code that does not know about the combination and the issues that can be caused.

Michael Feathers

Posts: 448
Nickname: mfeathers
Registered: Jul, 2003

Re: Mixins: Something Else You Can't Do With Java Generics? Posted: Oct 21, 2005 11:53 AM
Reply to this message Reply
> > This is the first time I've heard that called a
> "mixin."
> > It's the 'Curiously Recurring Template Pattern.'
> >
> > Jim Coplien wrote it up years ago.
>
> No, that's different. In CRTP, a new class inherits from a
> template instantiation that takes the new class as a
> parameter, like this (from Thinking in C++ Volume 2):
>
> class CountedClass : public Counted<CountedClass> {};
> class CountedClass2 : public Counted<CountedClass2> {};

Ooops. My bad. Thanks.

Tommy Carlier

Posts: 4
Nickname: tommyc
Registered: Oct, 2005

Re: Mixins: Something Else You Can't Do With Java Generics? Posted: Oct 22, 2005 4:19 AM
Reply to this message Reply
C# 3.0 has something that reminds me of mixins: extender methods.
You create a class, and add a static method that is attached to an existing class. Dumb example: I want to add a new method HasEvenLength to the string class:
public class MyExtenders {
public static bool HasEvenLength(this string s) {
return s.Length % 2 == 0;
}
}

Which can then be used like this:
string myString = "some string";
bool even = myString.HasEvenLength();

Bruce Eckel

Posts: 875
Nickname: beckel
Registered: Jun, 2003

Re: Mixins: Something Else You Can't Do With Java Generics? Posted: Oct 22, 2005 4:41 AM
Reply to this message Reply
Those appear to be what are called "Multimethods," which you can also find in the Nice language. But yes, another way to paste methods into an existing class. There seem to be a number of approaches to this, and I've never seen a comparison -- they tend to be expressed independently, without a sense of "what would mixins give you that multimethods wouldn't," etc.

Stephen Eldridge

Posts: 1
Nickname: stephen123
Registered: Oct, 2005

Re: Mixins: Something Else You Can't Do With Java Generics? Posted: Oct 22, 2005 10:09 AM
Reply to this message Reply
Are you sure erasure is the issue here?

You can't inherit from a type parameter in C# 2.0 either.
Just try
class TimeStamped<T> : T
and see.

Bruce Eckel

Posts: 875
Nickname: beckel
Registered: Jun, 2003

Re: Mixins: Something Else You Can't Do With Java Generics? Posted: Oct 22, 2005 10:50 AM
Reply to this message Reply
C# does a kind of "partial erasure" which is not as severe as Java's erasure. In C#'s case it is because generics have to work across the CLR, with languages that may not support generics.

Flat View: This topic has 27 replies on 2 pages [ 1  2 | » ]
Topic: Introducing Neon Previous Topic   Next Topic Topic: Persistent Hash-Tables and Why Wikipedia Still Sucks at Computer Science

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use