Harmony classes [Was: Operator overloading revisited]

Mark S. Miller erights at google.com
Mon Jul 27 08:46:11 PDT 2009

On Mon, Jul 27, 2009 at 2:56 AM, Tom Van Cutsem<tvcutsem at vub.ac.be> wrote:
>>>> const isSameDesc(desc1, desc2) { ... }
>>>> const addTrait(self, trait, opt_advice) {
>>>>  [...]
>>>>  if (oldDesc) {
>>>>    if (isSameDesc(oldDesc, newDesc)) {
>>>>       // already cool
>>>>    } else {
>>>>       Object.defineProperty(self, k, conflictDesc);
>>>>    }
>>>>  } else {
>>>>    Object.defineProperty(self, k, newDesc);
>>>>  }
>>>>  });
>>>> }
>>>> ------------------------
> It's really nice that you can specify trait composition in Javascript using
> metaprogramming this easily. I checked your implementation against our
> implementation of traits in AmbientTalk. There is one issue that we had to
> work around, which relates to "default properties" that are present in every
> object: we had to exclude such properties 'by default' since they would
> otherwise always cause conflicts.

That's why I put the isSameDesc() call into the conditional above. If
the same name is bound to the same descriptions into two different
traits being composed -- as would happen for example in a diamond
composition pattern -- then there's no conflict.

> My guess is that if such properties exist
> in JS, you would probably set their 'enumerable' field to false to filter
> them out.

The equivalent of default properties in JS are properties defined on
Object.prototype. Until ES5, all object necessarily inherited from
Object.prototype, and typically will still. The properties defined by
the spec on Object.prototype are indeed defined as non-enumerable. And
in ES5, new properties that anyone defines on Object.prototype can
(and therefore should) be defined as non-enumerable as well.

But none of that is why we avoid a conflict for such methods. Since
addTrait() enumerates properties with Object.getOwnPropertyNames(),
this enumerates all own properties whether enumerable or not. An "own"
property is a property defined directly on the object, as opposed to
an "inherited" property. So we avoid the defaults from
Object.prototype but we do compose non-enumerable properties. We dodge
the false-conflict problem with the isSameDesc() check explained


More information about the es-discuss mailing list