Traits library

Erik Arvidsson erik.arvidsson at
Tue Feb 16 16:57:44 PST 2010

Hi Tom,

I looked at your library a few weeks ago and I was pretty impressed by
it back then. (I'll take a second look but I'm sure more time has made
it even better.)

One serious omission in your library is that traits cannot (could
not?) be applied to existing objects. Adding traits to existing
objects is important because it allows you to combine prototype based
inheritance with traits by adding a trait to the prototype. Adding
traits to the prototype, in turn makes composition a one time cost
instead of per instance cost.

function MyComponent() {}
MyComponent.prototype = Object.create(MySuperClass.prototype);
addTrait(MyComponent.prototype, eventTargetTrait);
var c = new MyComponent;
c.addEventListener('foo', bar);

Keep up the good work,


On Tue, Feb 16, 2010 at 14:55, Tom Van Cutsem <tomvc at> wrote:
> Hi,
> Mark Miller and I have been working on a small traits library for
> Javascript. It is documented here:
> <>
> Traits are reusable building blocks for classes, very similar to mixins, but
> with less gotchas. For example, traits support explicit conflict resolution
> upon name clashes and the order in which traits are composed is not
> significant.
> In a nutshell:
> - The library is designed for ES5, but backwards-compatible with existing
> ES3 implementations.
> - Our library represents traits as ES5 property maps (objects mapping
> property names to property descriptors). The library exports:
>  - a convenient trait "constructor" to generate property maps from object
> literals.
>  - a number of "trait combinators" to compose property maps.
>  - a function that can "instantiate" such property maps into objects
> (analogous to the ES5 Object.create function, but with awareness about
> trait-specific property semantics).
> The interesting thing about our choice of transparently representing traits
> as ES5 property maps is that our library can be used as a general-purpose
> library for manipulating property descriptors in addition to its use as a
> library to compose and instantiate traits.
> A small expository example that uses the library:
> <>
> Mark and I were both surprised at how well Javascript accommodates a trait
> library with very little boilerplate. However, there is one catch to
> implementing traits as a library. Traits, like classes, are normally simply
> declared in the program text, but need not necessarily have a runtime
> representation. Trait composition is normally performed entirely at
> compile-time (in trait lingo this is called "flattening" the traits). At
> runtime, no trace of trait composition is left.
> Because we use a library approach, traits are not declarative entities and
> must have a runtime representation. Thus, there is a runtime overhead
> associated with trait creation and composition. Moreover, because the
> implementation is oblivious to traits, multiple objects instantiated from
> the same trait "declaration" don't share structure. However, we did design
> the library such that, if traits are specified using object literals and
> property renaming depends only on string literals (which is the common
> case), a partial evaluator could in principle perform all trait composition
> statically, and replace calls to Trait.create with a specialized
> implementation that does support structural sharing between instances (just
> like an implementation that notices multiple calls to Object.create with the
> same property descriptor map can in principle arrange for the created
> objects to share structure).
> Any feedback on our design is welcomed. In particular, it'd be interesting
> to hear how hard/easy it would be for an implementation to recognize the
> operations performed by our library in order to perform them statically.
> Cheers,
> Tom
> _______________________________________________
> es-discuss mailing list
> es-discuss at

More information about the es-discuss mailing list