19

It seems that in all class-based or prototypal OOP languages, mixins are either an afterthought or a secondary feature. However, to me it looks like traditional inheritance is just a specific case of using a single mixin.

I am assuming this is because of historical reasons and familiarity, but maybe there is something else? Problems with sharing encapsulated state safely?

14
  • 2
    Traits in Scala? Also, I don't think this really applies to languages such as Eiffel or C++ that allow multiple inheritance, where you can model any "abstract" class to be a "mixin".
    – SBI
    Nov 2, 2015 at 12:10
  • 1
    @gnat - the accepted answer there focuses on prototypal OOP "Prototypical inheritance is simple." - my question is more agnostic.
    – Den
    Nov 2, 2015 at 12:18
  • I feel it doesn't necessarily need to be a duplicate. However, there needs to be a distinction between language feature and modelling technique, such as using abstract or even concrete classes with few or a single method as a mixin.
    – SBI
    Nov 2, 2015 at 12:18
  • 2
    The question supposes that one needs a reason to not spend dozens of programmer-years making a new language whose compelling benefit is not that it solves some problem, but that it is built around a particular philosophy. New languages are insanely expensive; you need a reason to expend that effort, not a reason to not expend that effort! Nov 2, 2015 at 17:39
  • 1
    But every design process entails deciding what features will be flexible and which will be foundational. Flexibility is extremely expensive across many dimensions of language design; adding more flexibility often means deprioritizing things like performance or understandability. Nov 2, 2015 at 17:51

1 Answer 1

32

The seminal paper on mixins is Gilad Bracha's PhD thesis The Programming Language Jigsaw: Mixins, Modularity and Multiple Inheritance.

It has answers to all of your questions, like

  • Why not make a language with mixin-only inheritance?

    Jigsaw is such a language, as is Newspeak, Bracha's current language

  • However, to me it looks like traditional inheritance is just a specific case of using a single mixin.

Indeed, mixin inheritance subsumes all classical forms of single (class-based) inheritance (Simula-/Smalltalk-style inheritance as well as Beta-style prefixing), as well as multiple class-based inheritance with linearization (CLOS, C++, Python, …)

You may want to have a look at Newspeak. Don't be fooled by the fact that it has "classes". They are actually mixins. The Jigsaw paper describes how classes can be elevated to mixins, and that is exactly how it works in Newspeak.

Basically, a mixin is a class that doesn't know its superclass. Therefore, it can appear at multiple places in the inheritance tree. (Note that this is not multiple inheritance! It is, in fact, in some sense exactly the opposite or dual: in multiple inheritance, a class appears at a single place with multiple superclasses, in mixin inheritance, a class appears at multiple places with a single superclass.)

In Newspeak, OO is taken to the extreme: everything is a message send ("virtual method/function call" in Javanese/C++). Even superclass lookup. So, when you declare a class Sub as a subclass of Super, the superclass of Sub is not stored inside some pointer in the internal implementation of Sub, no, whenever you need the superclass (e.g. during message dispatch (virtual method/function lookup/dispatch in Javanese/C++)), the runtime interprets Super as the name of a method to call which returns a class. However, it is not known at runtime which class it returns. In fact, it might return a different class every time! Therefore, classes in Newspeak don't know their superclass, which is the/a definition of a mixin.

Note that in a prototype-based language, the idea of having a dedicated mixin makes no sense. The whole point of a prototype-based language is that there is only one kind of "things" (objects) as opposed to two kinds of "things" (objects and classes, objects and traits, objects and mixins, …). They can be used as a Design Pattern, of course. That's how they were originally invented, after all, in the Flavors object system for Lisp, which had classes with multiple inheritance, but the classes were often used in a peculiar way, which they called mixins (and from which the object system got its name).

6
  • 4
    For those without postscript viewers: citeseerx.ist.psu.edu/viewdoc/…
    – Jules
    Nov 2, 2015 at 17:51
  • 3
    Is there any consensus or general opinion about whether this is an effective way of organizing code? Does it really help anything, or is it just a neat idea that doesn't play out very practically?
    – jpmc26
    Nov 2, 2015 at 18:04
  • Excellent answer and that paper is fantastic. I disagree about the last paragraph though, prototype based languages can still have mixins as sugar for copying all properties over from one object for another. JavaScript had an Object.mixin at a point (which was renamed .assign) and has dedicated mixin syntax in the upcoming version (assuming that makes the cut). You can "mixin" two objects without a second "thing", it's not exactly Bracha's mixins in Jigsaw but it's the same concept. Nov 2, 2015 at 19:29
  • 1
    @KevinKrumwiede: In Java, as well as all other blass-based OO languages, a class doesn't know its subclasses. Yet, we can still talk about subclasses in a sensible manner. Why should superclasses be any different? When a mixin is mixed into a class, the mixin becomes the class's new superclass and the old superclass becomes the mixin's superclass. IOW: the mixin is inserted into the class hierarchy between the mixed-into class an its superclass. It works like any other class. It has a superclass. However, since it can appear multiple times, each time with a different superclass, it cannot … Nov 3, 2015 at 0:31
  • 1
    … make any assumptions about its superclass. Nov 3, 2015 at 0:31

Not the answer you're looking for? Browse other questions tagged or ask your own question.