The Composition Design Pattern

You may have heard the expression “prefer composition over inheritance“.

But what does it really mean? What’s wrong with inheritance? Even the Wikipedia article on composition over inheritance is using classes and inheritance to explain composition. If composition is so much better than inheritance (at least sometimes), then why do we have to explain composition in terms of inheritance? And why do most modern programming languages and platforms support classes and inheritance syntactically but not composition? What would a programming language even look like if it had syntactic support for composition? Furthermore, what even is the design pattern for composition?

Many of the examples you see from cursory searches online simply show one class containing references to others and that’s about it. This kind of overly simple example seems to acknowledge the problem without really explaining the full solution and it’s completely framed in a context of inheritance. Simply introducing classes containing references to other classes doesn’t give us enough information to establish a pattern and it ends up raising more questions than it answers.

One really good example of composition can be found in Unity3D. Composition in Unity3D is a first class concept that runs very deeply into the built-in game engine that drives everything that Unity does. After studying it for a while I would like to use the patterns of composition found in Unity as a basis for our design pattern and our hypothetical programming language.

Aspects of the Composition Pattern

In a compositional system you therefore need at least two kinds of Types:

  • Object
  • Component

The Object in a compositional system is not the same as an Object in an inheritance based system. An Object in a minimal compositional system has the following attributes:

  • It may have a name
  • It may posses child objects
  • It may have a parent object
  • It may contain named components
  • It can send messages to components

A Component has the following attributes:

  • It has a reference to the Object it is contained by
  • It may have data
  • It can handle messages

Simple Example

If we were to design a minimal version of this system (in C#) it may look something like this:


interface IObject
{
string Name { get; }
IObject Parent { get; }
void Add(string name, IComponent component);
void Add(IObject child);
void Remove(IObject child);
IComponent GetComponent(string name);
IEnumerable<IObject> GetChildren();
void SendMessage(string message, params object[] parameters);
}
interface IComponent
{
IObject Object { get; }
}

view raw

Design.cs

hosted with ❤ by GitHub


// A naieve implementation of SendMessage
public void SendMessage(string message, params object[] parameters)
{
var types = parameters.Select(a => a == null ? typeof(object) : a.GetType()).ToArray();
foreach (var component in this.components.Values)
{
var method = component.GetType().GetMethod(message, types);
if (method != null)
{
// Call methods on the component via reflection
method.Invoke(component, parameters);
}
}
}

view raw

SendMessage.cs

hosted with ❤ by GitHub

For a more robust example I highly recommend studying Unity3D in detail. However the question I am asking is what would a system like this look like if it was not framed in the context of classes. How would it look if it were to have syntactic support in a language instead of simply implemented as a design pattern in terms of inheritance? I don’t fully know the answer to this question but I have been experimenting with some ideas and would like to have a discussion around them.


component c1 {
function receive(message: string) { // handles "receive" messages
print(message)
}
}
component c2 {
var running: bool
function run() { // Handles the "run" message
if(!running)
running = true
this>receive("hello world!") // Sends a message to "receive" with an argument
else
this>receive("error!")
}
}
// An object containing the above components
var x = {
c1 = new c1()
c2 = new c2()
}
// send a message to components on x named "run"
x>run() // > hello world!
x>run() // > error!

view raw

Components.js

hosted with ❤ by GitHub


var x = { } // an empty object
var y = {
value: "hi" // any value type, not a function
}
var z = Root { // a named object
}
var j = Root { // An object with children
First {
}
Second {
}
}
for(var child in j) {
print(child.name) // First, Second
}
j.First.foo() // Get child named "First" send it a message named "foo"

view raw

Objects.js

hosted with ❤ by GitHub

The first thing to realize with this system is that instead of designing Objects up front with static definitions like classes you can only instantiate them and you can only design their hierarchy.

Components are more interesting and do have a static definition. They contain state like a class which means they fulfill the OO principle of encapsulation. They may handle messages of any shape which also means they are polymorphic but they are not inheritable in this system. You may be tempted to add inheritance to components at this point but I believe that this is unnecessary and a mistake. The reason for this is that inheritance is basically just another kind of relationship but it is one that has a much higher degree of coupling between objects. There are a variety of reasons why this form of relationship can cause problems. One is the lack of abstraction and thus isolating the unit for test can become very complex and costly. Instead of using inheritance simply break out shared behavior and state into even more, smaller and more focused components.

A composition system like this is actually similar to the DOM you would find in a browser. The primary differences are that in this case it would not be tied specifically to a single domain (e.g. the domain of laying out and rendering documents) and instead of using an event system it uses message passing. In this way composition allows us to be extremely loosely coupled without requiring extra abstractions.

I can imagine systems where, instead of having a component keyword in the language, you compile entire files into components similar to the way you would compile an entire file into a module in a CommonJS system such as node.js. Your main app would essentially setup your starting objects the rest of your files would be Components. These ideas are very powerful I believe. The game industry has known about them and has been perfecting them for quite some time now, while the rest of the programming community appears to be largely unaware as far as I can tell. I would love to see some experimentation with these ideas in non game domains and find out what the community can come up with.

Virtual Reality Language Workbench

Here’s a little sketch I made of a concept for a language workbench designed for use with an Oculus Rift and Razor Hydra. The idea is that you would have a “cockpit” view of your workbench. In the center of the view you would have a graphical representation of a pattern, which you could manipulate with the hydra. On the far left is a 2D toolbar for actions on the far right is an assortment of available patterns. To the left of the pattern is a view of some test input to the right is the production of the data through the pattern.

You would need a way to model complex data visually though, and the output view is dynamic based on the data. You would be able to zoom into the output display to see it as a running app. This is what’s rumbling around in my head these days…

vr_ide

MELT at the University of Minnesota

I was invited to the University of Minnesota today for a brief talk by Eric Van Wyk who presented over lunch about some of his research on extensible language tools. I was very surprised to find out that the research he has been doing is very similar to what I have been doing with meta#, they are working on ways to compose language extensions and create domain specific languages on top of general purpose languages. The details are different and some of them are very interesting and require further investigation but I am surprised by how much is not different.

Also, similar to the PPL and maybe even more so, he has a treasure trove of research papers on DSLs that I will have to read through.

Lang.NEXT 2012 overview

I had a great time at Lang.NEXT last week! There were a ton of amazing presentations and a lot of interesting conversations in between and after. There was a nice ongoing debate between native and managed languages and it was interesting to see some of what was going on in these fields.

What really interested me though was on the talks about Domain Specific Languages (of course). There was a talk about DSLs in Haskell and a talk on Bloom which is an internal DSL in Ruby and also a talk about R which is a DSL for statisticians.

But the one that really blew me away was the talk on pervasive parallelism in Scala, which turned out to be almost completely about the power of DSLs.

 

Specifically it was this slide that really got my attention:

image

Which is a pick2 diagram for programming languages, positioning DSLs as the solution for the problem of Productivity and Performance.

image

What was most amazing about this talk is that this is really the first time I’ve seen someone stand up and present DSLs with authority. And by that I mean someone who is making claims that are backed up by data and high quality research. When I talk about DSLs it’s based on my experiences and my intuitions and my understandings but not really very convincing data. The guys in the PPL however, really have some awesome papers on DSLs. I definitely felt validated to see such positive results and I hope this grants me some authority as well. When someone seems dubious of the promises of DSLs I can point them to the PPL and they can read for themselves the benefits that can be had.

In this talk Kunle Olukotun very clearly says that DSLs raise your level of abstractions and grant you a high level of developer productivity. He also brings up the very important concept of restriction in DSLs as a virtue. This is one very important fact that is not usually understood by advocates of internal-DSLs. Restriction is a very important key component to an internal DSL and is actually a virtue. From restricting the types you can use to what you can do with those types to the semantics and syntax of the language itself. For example, in a highly parallel application restricting your ability to mutate shared state is necessary, and making this restriction explicit in the language itself is actually a virtue of the language and helps to channel a developer into the path of least resistance. In many other languages they attempt to give you more features and less restriction but the opposite should be true for DSLs.

He even goes on to explain how patterns in the middle of their architecture can be considered ops for parallelism and how they use this for multiple DSLs. They even find overlapping parts of their domains that can be abstracted and shared between each other. This is really thinking about DSLs correctly, this is truly applying these ideas in a good direction. The PPL is using Scala for their runtime and they also use Scala to make restricted internal DSLs but I think this can apply for any language. He mentions that Scala has some good constructs for parallelism but also has some good features for making restricted internal DSLs. I think they ended up having to hack the Scala compiler some, but I am not completely sure.

 

One problem remains however… It takes about this many PhD students and faculty to make a DSL.

image

image

 

I’m working on that.  🙂