Mix In

MixIn programming is a style of software development where units of functionality are created in a class and then mixed in with other classes.

A mixin class is a parent class that is inherited from - but not as a means of specialization. Typically, the mixin will export services to a child class, but no semantics will be implied about the child "being a kind of" the parent.

A MixIn is also called an AbstractSubclass since MixIn can provide other services based on the services the original class provides.

Mixins are controversial because the prescribed way of providing such services is by association. However, they are useful because inheritance places the services within the child itself. For this reason they are commonly found in windows class libraries where there is a need for certain features to be generalized for "mixing in" later.


Actually Mixins are only 'controversial' because people try to use them in languages with no support for them. This makes all kinds of problems. See the Flavors mixins.


Also see MixinsForCeePlusPlus


Mixins are coming from Flavors. Flavors is an early Object System for the LispMachine.

Imagine you have vanilla ice where you can add in different stuff. So the base class in Flavors was called Vanilla. Parts of the Lisp Machine operating system were programmed using mixins. An example is the window system, where you can mixin borders-mixins into window classes. So it does not mixin the borders itself, but adds the feature that the window has borders. In Flavors the classes slots are extended AND (and that is the big AND) the methods get extended OR overwritten, too. In the case of the border-mixin the idea is that it also extends (!!) the window-draw method to draw the borders.

CommonLisp also supports the mixin style of programming. Most other programming languages make it difficult, because they don't have MethodCombinations.

See: David A. Moon. Object-oriented programming with Flavors. In Proc. First Annual Conference on Object-Oriented Programming Systems, Languages, and Applications. ACM, 1986.


An example for the mechanism using the CommonLispObjectSystem:

(defclass window ()
  ((width
:accessor window-width
:initarg :width
:type integer
:initform 200)))

(defclass border-mixin () ((border-width :type integer :initarg :border-width :initform 1)))

This next function is the key element, which is not really possible in most object oriented languages. Most don't have :around, :before or :after methods. This facility is known as MethodCombination.

(defmethod window-width :around ((window border-mixin))
(+ (call-next-method)
(* 2 (slot-value window 'border-width))))
Now we define our own window class, which also inherits from our mixin class:

(defclass my-window-with-border (border-mixin window)
  ())
An instance:

(defvar *my-window* (make-instance 'my-window-with-border
:width 400
:border-width 10)
We call the WINDOW-WIDTH method, which then runs the :AROUND method around the primary WINDOW-WIDTH method. So it computes (+ width (* 2 border-width)) :

(window-width *my-window*)  ->  420


Do you really need full-fledged MethodCombination, or is it enough to have a well-defined class-precedence list and the ability to call the next method in the list? I'm thinking of DylanLanguage, which doesn't have MethodCombination, but does copy CommonLisp's GenericFunction paradigm, along with how to compute the class precedence list. It seems like the above example could be done just by translating the classes into Dylan syntax and then writing window-width like this:

  define method window-width (window :: <border-mixin>)
next-method() + 2 * window.border-width;
  end window-width;

You do have to make sure that <border-mixin> precedes <window> in the class hierarchy for <my-window-with-border>, but it seems like you would run into that problem even with CLOS if you ever tried to combine 2 or more mixins (since the various :around methods get ordered by the class precedence list too).


Well, in this case the ordering is not important for the CLOS example. All :AROUND methods are used.

In CLOS one could also use a + method combination, where the results of all methods get collected. So, you would define a bunch of WIDTH methods for the various elements that contribute to the window width and have them added by the method combination.


The word "mixin" comes from Steve's Ice Cream, a favorite ice cream shop of MIT students located in Somerville, Mass., in the late '70s. Steve's made its own (very rich) ice cream in a motorized old-fashioned ice cream maker in the window of the shop. Sometimes the line for an ice cream cone was out the door and down the block!

You would order a cone or dish, and specify the base flavor and any mixins you wanted. The person behind the counter would plop your scoop of ice cream on a marble slab, dump a spoonful of mixins on top, and knead the two together, using two metal spatulas. My personal favorite was chocolate ice cream with crushed Oreo cookies mixed in. -- StanSilver

"The term mixin comes from an ice cream store in Somerville, Massachusetts, where candies and cakes were mixed into the basic ice cream flavors. This seemed like a good metaphor to some of the object-oriented programmers who used to take a summer break there, especially while working with the object-oriented programming language SCOOPS." (SAMS Teach Yourself C++ in 21 Days, 4th ed., p. 458.)


The grapevine informs me that Symbolics' object-oriented Flavors system is most likely the earliest appearance of bona fide mix-ins. The designers were inspired by Steve's Ice Cream Parlor in Cambridge, Massachusetts where customers started with a basic flavor of ice cream (vanilla, chocolate, etc.) and added any combination of mix-ins (nuts, fudge, chocolate chips, etc.). In the Symbolics system, large, standalone classes were known as flavors while smaller helper classes designed for enhancing other classes were known as mix-ins.

[From Chuck Esterbrook's article in Linux Journal #84 April, 2001 http://noframes.linuxjournal.com/lj-issues/issue84/4540.html]


One interesting way in which mixins are used in the CommonLispObjectSystem is by having them add to the list of applicable methods. E.g., you might have a class base, and a class derived, which want to specialize method foo. But you might also want to, say, add notification, as in an ObserverPattern. You create the observed-mixin, and do

(defclass derived (base observed-mixin)
())

(defmethod foo ((self base)) ;; do foo type stuff )
And the author of the mixin can write
(defmethod foo :after ((self observed-mixin))
(notify-all-observers (format nil "~A is being fooed!" self)))
This doesn't change anything to how foo acts on a derived, but lets all derived that want to be observed do so by simply inheriting the mixin. The use of the :before after :after methods that are part of the standard MethodCombination makes this a handy pattern in the CommonLispObjectSystem.


In addition to the CommonLispObjectSystem, the XoTclExtension (for the ToolCommandLanguage) has good support for mixins.


Also see MixinsForPython


CategoryPolymorphism

It has become doubtful as to whether MixIn techniques can be called polymorphism. According to NonPolymorphicInheritance, using a MixIn does not entail delegation (see WhatIsDelegation), and so lacking the requisite indirection, does not have polymorphic behavior.

Delegation does not imply polymorphism (though in some cases it does). See DifferentStylesOfDelegation

This is true, but delegation + indirection = PolyMorphism. See WhatIsDelegation. MixIn does not require indirection.

I'm not sure I grok what you mean by "indirection" here -- polymorphism is usually defined in terms of type substitutability, however that is implemented. If you are referring to how vtables work (a virtual function call in CeePlusPlus gets an extra level of indirection compared to a non-virtual call)...that's an implementation detail. An important one to be sure, but not fundamental to polymorphism.

Many other languages don't have vtables like C++, they perform name lookup at runtime.

Vtables or pick-your-preferred-implementation-details are not relevant, PolyMorphism is not fundamentally dependent on types, and focusing on substitutability has some subtle problems (see WhatAreTypes).

Please grok NonPolymorphicInheritance. The point made there is that a MixIn can be implemented without any polymorphism whatsoever. This kind of MixIn is for implementation reuse, not type substitution, and does not have polymorphic behavior.


Nobody pointed out RubyLanguage in this page. Most of the Ruby world is based around MixIns via Modules. Worth noting that Observable is_a MixIn in ruby similar to the example class from CommonLispObjectSystem. Still, decorating methods is quite more ugly in Ruby. Ruby even allows you to add a MixIn to a single object like:

 class << my_object
  include MixInModule?
 end
Is this considered AlloMorphism?

-- I don't know what you mean by "decorating methods", so I'll have to re-read this page. -- GavinSinclair

I think it means method decorators, like ":before", ":after", ":around", etc. -- JohnDuncan

-- However, the Ruby concept/implementation of mixins is the complete opposite of ugly. For example, Comparable is a module (namespace for a collection of methods) that defines the methods <, <=, ==, !=, >=, and >, all based on the comparison operator "<=>". So I can define a class that can be compared - say Name, and then mix in the Comparable module to get all those methods for free:

class Name
  attr_accessor :first, :middle, :last# getter and setter methods
  def initialize(f, m, l)
    @first, @middle, @last = f, m, l
  end

# Here's the comparison operator. def <=>(other) [@first, @middle, @last] <=> [other.first, other.middle, other.last] end

# Here's the good bit - I get <, <=, etc. for free. include Comparable end

n1 = Name.new('John', 'Q', 'Smith') n2 = Name.new('John', 'M', 'Schmidt')

n1 < n2# false n1 >= n2 # true # etc.
An even better example is the built-in Enumerable module, which provides methods like 'find', 'find_all', 'include?', 'map', 'sort', and several others, all based on the method 'each', which iterates over a collection. All of Ruby's collection-style classes therefore have all these methods. And if you write a collection-style class, you can 'include Enumerable' and get all these really powerful methods for free. Understanding Ruby's 'each' method is difficult for those not already familiar with Ruby, though. See BlocksInRuby for that.

-- GavinSinclair


A little sample in ScalaLanguage:

class Point2D(xc: Int, yc: Int) {
  val x = xc;
  val y = yc;
  override def toString() =
"x = " + x + ", y = " + y;
}
class ColoredPoint2D(u: Int, v: Int, c: String)
extends Point2D(u, v) {
  var color = c;
  def setColor(newCol: String): Unit = color = newCol;
  override def toString() =
super.toString() + ", col = " + color;
}
class Point3D(xc: Int, yc: Int, zc: Int)
extends Point2D(xc, yc) {
  val z = zc;
  override def toString() =
super.toString() + ", z = " + z;
}
class ColoredPoint3D(xc: Int, yc: Int, zc: Int, col: String)
extends Point3D(xc, yc, zc)
with ColoredPoint2D(xc, yc, col);
And new ColoredPoint3D(1, 2, 3, "blue").toString() would return "x = 1, y = 2, z = 3, col = blue".


See also: the TraitsPaper.


CategoryLanguageFeature


Having glanced briefly at much of this page and spent more time on a few parts, it seems that a lot of confusion and controversy could be prevented if we avoid using the language of inheritance to describe the Mixin. In particular, I find the first few lines talking about "inheriting" but saying the child is not the same kind of thing as the parent class contradictory. After all: long before anyone thought of applying the language of 'hierarchy' -- with all the implications from Aristotle's Categories -- to OOP, it has always been understood: the child is the same kind of thing as the parent, else the hierarchy is badly broken. Remember that this language was developed before anyone had to deal with the problems of hierarchies changing over time as evolution took place!

So I propose that instead of calling the classes 'parent' and 'child', and instead of saying the child 'inherits' from the parent, we should call the Mixin phenomenon "alien adoption", since this makes quite clear that the child is NOT the same kind of thing the parent is, but has only what the adopting parent has granted to it.

Is it not indeed the case that the use of Mixins really is different from OOP? If so, then this language makes that clearer, too.


EditText of this page (last edited November 1, 2011) or FindPage with title or text search