Another Approach To Mixins (First Draft)
========================================


Synopsis 
--------

We discuss a different style of Javascript mixins, one that creates a mixin 
function for a given API and a particular initialization function.  It is
both simpler to use and more flexible than many compteting techniques.



The Problem 
-----------

Mixins in Javascript have been [discussed often][gs1]. There are many 
implementations, although the basic patterns are much the same. But there has 
always been something unsatisfying about any of them, and I have been struggling 
to figure out a way to handle the conflicting pressures that mixins demonstrate. 

[gs1]: https://www.google.com/search?q=javascript+mixin

On a recent bus ride I scratched out a possible solutions for this (pencil and 
paper -- yes, I'm that old!) and put it aside until I ran across Peter Michaux's 
[new article][pm1]. That made me want to see if my idea could work in practice. 
So I've tried it, and I think it's worth sharing. 

[pm1]: http://peter.michaux.ca/articles/mixins-and-constructor-functions

Peter's article used the constructor `Observable`, and I will stick with that 
for most of my examples. Here is one version of that constructor: 


>     var Observable = function() {
>         this.observers = [];
>     };
>     Observable.prototype.observe = function(observer) {
>         this.observers.push(observer);
>     };
>     Observable.prototype.notify = function(data) {
>         for (var i = 0, ilen = this.observers.length; i < ilen; i++) {
>             this.observers[i](data);
>         }
>     };

A mixin takes an API like `Observable` and adds it to a different object, often 
to the prototype for another constructor function. The API can be arbitrary, but 
there is one caveat with most mixin techniques: if any initialization is 
necessary for the API to work, it needs to be run on all instances of the 
mixin target.  Thus if we have a constructor like the following:

>     var Person = function(name) {
>         this.setName(name);
>     }
>     
>     // somehow mixin Observable to Person
>     
>     Person.prototype.setName = function(name) {
>         var oldName = this.name;
>         this.name = name;
>         this.notify({oldName:oldName, newName:this.name});
>     }

We will have a problem with this:

>     var person = new Person("steve");

because it will be looking for `this.observers`, which won't exist. One 
technique that I've used before, and the one that Peter's article suggests, is 
to add a call to the `Observable` constructor inside the `Person` constructor: 

>     var Person = function(name) {
>         Observable.call(this);
>         this.setName(name);
>     }

This works fine, but it causes us to have to know about the mixin when writing 
the constructor. In this case, that's not an issue, since the `Person` prototype 
already uses one of the mixin methods (`notify`) but it's an odd intrusion in 
the general case. 

I would really like a technique that handles this for us. The problem is that 
when we mix our API into a constructor, there is no actual instance for us to 
modify. There seems to be no opportunity to run the initialization code except 
inside that constructor, unless we accept the ugly possibility of wrapping the 
work of each of our mixin's methods inside `if`-blocks that check to see if the 
initialization has been run, running it if not. We like clean code; we really 
don't want that. For a long time, I thought this was an intractable issue, but 
I've recently been working with an approach that seems to solve it. 



A Possible Solution
-------------------

What if we could run some one-time initialization exactly in the case that our 
mixin API is accessed? That would take care of this thorny issue. 

It turns out that this is not too hard to do. It's simply an extension of the 
notion of lazy-loading of functions, a topic well-covered in another excellent 
[article][pm2] by Peter Michaux. The only real difference is that in our case, 
instead of replacing a single function, we replace all the functions from the 
mixin API. Here's one implemenation of this concept: 

>     var createMixinApi = function(api, initFn) {
>         var name, result = {};
>         var createRealApi = function() {
>             var method = Array.prototype.shift.call(arguments);
>             initFn.call(this);
>             for (name in api) {if (api.hasOwnProperty(name)){
>                 this[name] = api[name];
>             }}
>             return this[method].apply(this, arguments);
>         };
>         for (name in api) {if (api.hasOwnProperty(name)) {
>             result[name] = (function(name) {
>                 return function() {
>                     Array.prototype.unshift.call(arguments, name);
>                     return createRealApi.apply(this, arguments);
>                 }
>             }(name));
>         }}
>         return result;
>     };

[pm2]: http://michaux.ca/articles/lazy-function-definition-pattern


## Explanation ##

That's a bit of a mouthful. Let's break it down a bit. Here is the actual 
function that will be mixed in to the target as the property whose name is 
represented by the variable `name`: 

>                 function() {
>                     Array.prototype.unshift.call(arguments, name);
>                     return createRealApi.apply(this, arguments);
>                 }

So after calling this:

>     extend(Person.prototype, createMixinApi(Observable.prototype, Observable))

Person.prototype would look something like this:

>     {
>          setName: function(newName) {
>              /* existing implementation */
>          },
>          observe: function() {
>              Array.prototype.unshift.call(arguments, name);
>              return createRealApi.apply(this, arguments);
>          },
>          notify: function() {
>              Array.prototype.unshift.call(arguments, name);
>              return createRealApi.apply(this, arguments);
>          }
>     }

This does not look too promising. Obviously `observe` and `notify` should not 
have the same exact implementation. But in fact they don't. They are bound to 
different closures. And the `name` variable in the two functions is bound 
differently in their closures (to 'observe' and 'notify'.) When we call the 
functions, this makes all the difference.

Once one of these functions is invoked on the `Person` instance, though, the 
initialization is run, and all of them are replaced with the actual API of 
`Observable`.   If you understand how that happens, feel free to skip the next
section.


## Code Walkthrough ##

We'll examine in detail what happens when we do this:

>     var person = new Person("Steve");


The `Person` constructor is invoked with the parameter "Steve". This calls the 
prototype `setName` function, passing "Steve". The third line of that function 
calls the `notify` method passing an object with the old and new names. This is 
the first usage of the mixed in code, and it's where things get interesting. 

We call the prototype `notify` function, and when we enter this function, we have 
these variables available: 


Name            | Defined in               | Value
----------------|--------------------------|----------------------------------------------
arguments       | local function scope     | ["Steve"] (an Arguments object, not an array)
this            | local function scope     | `Person` object
name            | outer closure            | "notify"
api             | inner closure            | {notify: [a function], observe: [a function]}
createRealApi   | inner closure            | [a function]
initFn          | inner closure            | The `Observer` constructor function
<del>name</del> | <del>inner closure</del> | <del>"notify"</del>


Note that the `name` property from the inner closure is shadowed by the `name` 
property from the outer closure. Although they have the same value right now, 
that is only because the order they were iterated in the order they appeared in 
the original `Observable` definition. (Had `observe` been defined after 
`notify`, then `name` in the inner closure would now have the value "observe".) 


Now we unshift the value `name` onto the `arguments` pseudo-array and call the 
`createRealApi` function.  Inside that function, here are the variables:


Name            | Defined in               | Value
----------------|--------------------------|----------------------------------------------
arguments       | local function scope     | ["notify", "Steve"]
this            | local function scope     | `Person` object
api             | closure                  | {notify: [a function], observe: [a function]}
createRealApi   | closure                  | [a function]
initFn          | closure                  | The `Observer` constructor function
name            | closure                  | "notify"


In this function, we pull the method name out of `arguments` and call the 
initialization function we supplied, which in this case is the `Observable` 
constructor. That is called in the context of our new `Person` object. (This is 
the step I didn't want to do inside the `Person` constructor.) 

Then we add all the functions from the mixin to our instance. Note that these 
functions will shadow the ones in the `Person` prototype. At this point, we now 
have the initialization of `Observable` completed inside our `Person` instance. 
All that remains is to complete the call we were trying to make in the 
beginning, which is accomplished by this line: 

>             return this[method].apply(this, arguments);


Refinements
-----------

The API This presents is still rather clunky. To actually use it, we need to 
depend on an external `extend` function, and we don't have a great location to 
store our new mixin API. 

The latter problem has a reasonable solution: Why not store it as a property of 
the `Observable` constructor itself? As to the former problem, Angus Croll makes 
a [good case][ac1] for thinking of such mixin APIs as functions rather than as 
static objects.  Combining these, we would like an API That looks something like this:

[ac1]: http://javascriptweblog.wordpress.com/2011/05/31/a-fresh-look-at-javascript-mixins/

>     Observable.mixinTo = createMixin(Observable.prototype, Observable);
>     
>     // ... and then later ...
>      
>     Observable.mixinTo(Person.prototype);


We can turn the above into such a reusable function-generator in a fairly 
straightforward manner: 

>     var createMixin = (function() {
>         var extend = function(destination, source) {
>             for (var name in source) {if (source.hasOwnProperty(name)) {
>                 destination[name] = source[name];
>             }}
>             return destination;
>         }
>         var createMixinApi = function(api, initFn) {
>             var name, result = {};
>             var createRealApi = function() {
>                 var method = Array.prototype.shift.call(arguments);
>                 initFn.call(this);
>                 for (name in api) {if (api.hasOwnProperty(name)){
>                     this[name] = api[name];
>                 }}
>                 return this[method].apply(this, arguments);
>             };
>             for (name in api) {if (api.hasOwnProperty(name)) {
>                 result[name] = (function(name) {
>                     return function() {
>                         Array.prototype.unshift.call(arguments, name);
>                         return createRealApi.apply(this, arguments);
>                     }
>                 }(name));
>             }}
>             return result;
>         };    
>         return function(api, initFn) {
>             var mixin = createMixinApi(api, initFn);
>             return function(destination) {
>                 return extend(destination, mixin);
>             };
>         };
>     }());

There is still one bit of clean-up that remains. For our current example, and 
probably for many others, the initialization function and the API to mixin are 
intimately related, as the former is a constructor function and the latter its 
prototype. There is definitely a bit of code smell to repeating the construtor 
name in this: 

>     Observable.mixinTo = createMixin(Observable.prototype, Observable);

I probably would not want to eliminate the first use of `Observable` because, 
while it might sometimes be convenient to simply call a function passing a 
constructor as a parameter, the code would be considerably less readable to 
someone who didn't know what the Mixin function did. But the other two are 
clearly repetitive. It would be cleaner, in this case, to simply call: 

>     Observable.mixinTo = createMixin(Observable);

But there are other ways we would want to use this, ways in which the 
relationship between the API to mix in and initialization function is not so 
simple. I'll explain a few below. This means we wouldn't want that version of 
the function to be the only version available.   To deal with this conflict, 
we could present any of these variations: 

>     Observable.mixinTo = Mixin.create(Observable);
>     var someOtherMixinFunction = Mixin.create(someAPI, someInitializater); 

or

>     Observable.mixinTo = Mixin.create(Observable);
>     var someOtherMixinFunction = Mixin.createApi(someApi, someInitializater); 

or 

>     Observable.mixinTo = createMixin(Observable);
>     var someOtherMixinFunction = createMixin.forApi(someApi, someInitializater); 

The first variation seems very popular these days in Javascript. The jQuery API, 
for instance, uses a great deal of method overloading. I'm not thrilled with 
this idea, myself; I don't think the smaller conceptual footprint is enough to 
outweigh the additional complexity in parameter handling. But its certainly a 
viable option. 

The second variation is probably the most conventional. There is nothing wrong 
with it, and it would be easy to implement. But I find the third one more 
interesting, and perhaps slightly cleaner to use. So that is what I'll present 
as my completed API: 

>     var createMixin = (function() {
>         var extend = function(destination, source) {
>             for (var name in source) {if (source.hasOwnProperty(name)) {
>                 destination[name] = source[name];
>             }}
>             return destination;
>         }
>         var createMixinApi = function(api, initFn) {
>             var name, result = {};
>             var createRealApi = function() {
>                 var method = Array.prototype.shift.call(arguments);
>                 initFn.call(this);
>                 for (name in api) {if (api.hasOwnProperty(name)){
>                     this[name] = api[name];
>                 }}
>                 return this[method].apply(this, arguments);
>             };
>             for (name in api) {if (api.hasOwnProperty(name)) {
>                 result[name] = (function(name) {
>                     return function() {
>                         Array.prototype.unshift.call(arguments, name);
>                         return createRealApi.apply(this, arguments);
>                     }
>                 }(name));
>             }}
>             return result;
>         };    
>         var create = function(api, initFn) {
>             var mixin = createMixinApi(api, initFn);
>             return function(destination) {
>                 return extend(destination, mixin);
>             };
>         };
>         var createConstructorMixin = function(ctor) {
>             return create(ctor.prototype, ctor);
>         }
>         createConstructorMixin.forApi = create;
>         return createConstructorMixin;
>     }());


Advantages
----------

### Simplicity ###

The biggest advantage to this mixin strategy that I see is just how clean it is. 
You can create a mixin out of any API in a single line of code, and mix it into 
any other API with just one more. Neither the source nor the destination needs 
to know anything about the other. 


### Flexibility ###

But it is also flexible.  Imagine an API that looks like this:

>     // creates Logger instances that can store and display log messages
>     var Logger = function() {
>         // initialize various listeners, do other setup
>     };
>     Logger.prototype = {
>         debug: function(msg) { /* ... */ }, // default: ignored
>         info: function(msg) { /* ... */ },  // default: console.info
>         warn: function(msg) { /* ... */ },  // default: console.warn
>         error: function(msg) { /* ... */ }, // default: console.error
>         addListener: function(msgTypes, newListener) { /* ... */ },
>         getMessages: function(type) { /* ... */ },
>         enable: function(type) { /* ... */ },
>         disable: function(type) { /* ... */ },
>     };

If we would like to create a mixin out of this so that other objects could use 
its implementation of `info`, `warn`, and `error`, but did not want the entire 
Logger API mixed in, we could use the our mixin like this: 

>     Logger.mixinTo = createMixin.forApi({
>         info: Logger.prototype.info,
>         warn: Logger.prototype.warn,
>         error: Logger.prototype.error
>     }, Logger);
>     
>     // ... later ...
>     
>     Logger.mixinTo(MyObject.prototype);

If we also wanted the `getMessages` functionality, but were concerned that this 
name was too generic for our mixin, we could simply alias it as 
`getLogMessages`: 

>     Logger.mixinTo = createMixin.forApi({
>         info: Logger.prototype.info,
>         warn: Logger.prototype.warn,
>         error: Logger.prototype.error,
>         getLogMessages: Logger.prototype.getMessages
>     }, Logger);


Or if our Logger constructor created a number of instance properties that were 
unnecessary for our mixin case, we could instead use a custom function as the 
initializer. This would require some knowledge of how the `Logger` constructor 
worked. Let's imagine, for instance, that if we don't need the `addListener`, 
`enable`, or `disable` properties of Logger, and that therefore the only 
initialization required is to add the single property, `messageStore`, to our 
instance. Then we can supply a simple function like this: 

>     Logger.mixinTo = createMixin.forApi({
>         info: Logger.prototype.info,
>         warn: Logger.prototype.warn,
>         error: Logger.prototype.error
>     }, function() {
>         this.messageStore = [];
>     });


But perhaps we really want to expose a partial API delegating all calls to an 
instance created by the underlying constructor. We could do the following as a 
one-off: 

>     Logger.mixinTo = createMixin.forApi({
>         info: function() {return this.logger.info.apply(this.logger, arguments);},
>         warn: function() {return this.logger.warn.apply(this.logger, arguments);},
>         error: function() {return this.logger.error.apply(this.logger, arguments);}
>     }, function() {
>         this.logger = new Logger();;
>     });

Or if we thought this was common, we could add to our function something that 
would allow us to do: 

>     Logger.mixinTo = createMixin.delegatedApi(["info", "warn", "error"], Logger);
>     
>     // ... and then later ...
>      
>     Logger.mixinTo(MyObject.prototype, "logger"); // second param is delegate name
>     
>     // ...
>      
>     var obj1 = new MyObject(/* params */);
>     // next line resolves to obj1.logger.warn("Problem found!");
>     obj1.warn("Problem found!");

We'll leave details of how to write that as an excersize for the reader.

Also note that although we've mostly discussed mixing into the prototypes of 
constructor functions, in fact we can mix in to any object at all. 

>     var obj1 = new MyObject(/* params */);
>     Logger.mixinTo(obj1);
>
>     var obj2 = {
>         method1: function() {/* ... */},
>         method2: function() {/* ... */}
>     };
>     Logger.mixinTo(obj2);


Disadvantages
-------------

### Memory Usage ###

One issue that might be significant is that this style takes more memory than a 
pure constructor function approach. Each instance gets its own references to 
each mixed in API function. Or at least it gets them when the API is actually 
used; until then it simply inherits the wrapper functions attached to its 
constructor. Note though that it does not get its own copy of the **function**, 
only a copy of the **reference to that function**. So the memory overhead is not 
huge, but it's real, and there is no way to eliminate it. 

### Running the Prototype Functions Wreaks Havoc ###

Since in Javascript prototypes are simply plain objects, any of these wrapped 
functions could be called as methods of the prototype. No one should ever do 
something like this, of course, but if it did happen, it would cause significant 
problems. The initializer would run on the prototype, adding whatever properties 
it expected to add on an instance. The prototype wrapper functions would be 
replaced by the underlying API. All future instances created from that prototype 
would share a single state as would all instances that have not yet had their 
own wrapper functions replaced. This would be bad<sup>TM</sup>. 

But that is not a problem specific to this technique. It would happen for any 
lazily instantiated instance properties created by functions on a prototype: 


>     Person.prototype.addFriend = function(friend) {
>         if (!this.friends) {
>             this.friends = [];
>         }
>         this.friends.push(friend);
>     };

If `addFriend` was called on the prototype, then all `Person` instances that 
have not yet had their own list of friends initialized (including all new Person 
objects) would share a single list of friends. So, while this is a concern, it 
seems to be more a case of "Doctor, it hurts when I do this. So don't do that." 



And Th-th-th-that's All, Folks
------------------------------

This seems to be a useful technique, and it shows off some of the wonderful 
dynamic nature of Javascript. 

Please feel free to look at [the complete source][source] or the 
[unit tests][tests], and [let me know][mailme] about any suggestions.

[source]: http://not.yet.ready/
[unit tests]: http://not.yet.ready/
[mailme]: mailto:scott.sauyet@gmail.com


#### Created May 3, 2012.  Last updated May 3, 2012 ###