Traits library

Mark S. Miller erights at
Wed Feb 17 16:30:43 PST 2010

On Wed, Feb 17, 2010 at 2:42 PM, P T Withington <ptw at> wrote:

> On 2010-02-16, at 17:55, Tom Van Cutsem wrote:
> > Hi,
> >
> > Mark Miller and I have been working on a small traits library for
> > Javascript. It is documented here: <
> >>
> Nicely done.  A couple of high-level questions.  [Full disclosure:  I'm
> with OpenLaszlo, and we have our own class/mixin implementation based on
> prototypical inheritance, built around some extra syntax, transformed by our
> compiler, and a runtime library; all running in es3 (and as2 and as3).  We
> haven't yet thought about how we might take advantage of es5.]
> 1) I understand the motivation for traits (removing some of the magic of
> mixins), but I don't understand why that needs to be anything more than a
> lint-like tool, rather than insinuating itself into the implementation.  The
> fact that you provide the order-sensitive `override` compositor weakens the
> case for strict traits.  If override combination somehow made the overridden
> property accessible with a standard name (`super`), it seems to me you would
> have mixins.  What am I missing?
> 2) Could you elaborate on this:
> > The renaming performed by resolve is shallow: it only changes the binding
> of the property. If the property is a method, it will not change references
> to the renamed identifier within the method body.
> It seems to me that this 'feature' could lead to more magic than mixins.
>  If I read this correctly, overriding a method in a trait will be visible to
> methods outside the trait, but not to methods inside the trait.  That
> doesn't seem to follow the original traits composition principles.
> 3) In our usage, being able to test that an object "is" an instance of a
> mixin is quite important.  In your description, you imply that type testing
> is an exercise left to the future.  Has this not been an issue in applying
> your traits library?
> 4) Your 'stateful trait' example shows why I would call 'class state' and
> 'each-subclass state' (with the latter recommended, but the former could
> have applications).  Because your implementation allows any type of property
> (not just methods), you also have 'instance state' in your traits.  I think
> this is a good thing.  Perhaps you should make that more explicit, since it
> diverges from the traits references.
> 5) I've lost track of where Harmony is heading with classes, but do you
> have any thoughts on that?  Do you see you traits as an alternative to any
> other class proposal, or would it be intended as an extension of classes (as
> the original traits proposal was), should they ever arrive?

Tom & I started with the question "If we could have any syntactic sugar we
wanted, how would we express traits?". Once we had a plausible answer, we
asked "How close could we come with a pure library, with no new syntactic
sugar?". The answer was, so close that the remaining benefit of additional
syntax was tiny, so we dropped it.

Allan and I had previously agreed that the overlap in functionality between
his extended object literal syntax <>
and my classes-as-sugar proposal (<> and <>) is
sufficiently great that only one or the other should become part of future
ES. I would add traits to the list. All three provide, in some sense,
extended object literals for high integrity objects, and with similar
implementation burdens to avoid per-instance bound method allocation cost.
But they do so in very different ways, and with different flexibilities
beyond their common core functionality.

Of the three, I would rather see Tom's traits than either my
classes-as-sugar or Allan's extended object literal syntax. But as long as
we get efficient high integrity objects without undue complexity, I am
rather happy.

For comparison, the classes-as-sugar example at <>

    class Point(privX, privY) {
      let privInstVar = 2;
      const privInstConst = -2;
      public toString() {
        return ('<' + getX() + ',' + getY() + '>');
      public getX() { return privX; };
      public getY() { return privY; };
      public let pubInstVar = 4;
      public pubInstConst = -4;

rewritten using Tom's traits:

    function Point(privX, privY) {
      let privInstVar = 2;
      const privInstConst = -2;
      let pubInstVar = 4;
      const pubInstConst = -4;
      return Trait.object({
        toString: function() {
          return ('<' + this.getX() + ',' + this.getY() + '>');
        getX: function() { return privX; },
        getY: function() { return privY; },
        get pubInstVar() { return pubInstVar; },
        pubInstConst: pubInstConst

with the caveat that the two Object.freeze()s are manually hoisted to the
beginning of the block in which Point is defined. Given only the const
function sugar proposed at the top of <>, even
this remaining annoyance would go away.

> P T Withington
> OpenLaszlo.ORG/Laszlo Systems
> _______________________________________________
> es-discuss mailing list
> es-discuss at

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list