What do we still need from a class-like abstraction (was: `this`: methods versus functions)

Andreas Rossberg rossberg at google.com
Thu Nov 10 08:56:24 PST 2011


I wholeheartedly agree that mixin composition is superior to both
prototype and class-based inheritance. I'm not sure I entirely follow
your point regarding `this', though.  (TBH, I'd prefer not having a
`this' keyword at all, because not being alpha-convertible, it doesn't
really compose with nested definitions, and invites subtle mistakes --
a lightweight syntax for binding an arbitrary identifier to self seems
better.)

The traits proposal currently is nice indeed, but also quite heavy on
going through reflective meta levels. It will require significant work
to make that efficient.  But I believe there is potential for VMs
optimizing e.g. nested closure creation for certain patterns.  Though
obviously, implementers currently have other priorities (like catching
up with ES6 features first :) ).

/Andreas


On 10 November 2011 16:59, Mark S. Miller <erights at google.com> wrote:
> Note that the traitsjs library provides:
> 1) all the safety of the objects-as-closure pattern you show below (and more
> because it takes care of the needed freezing).
> 2) still allows intuitive use of "this" to refer to the instance itself,
> bound not lexically, but rather at object instantiation time. This enables
> 3) a superset of conventional oo inheritance and override patterns, where
> the lookup of "this.getX()" is determined by the concrete "subclass", rather
> than either the lexical occurrence of "this" or "self" (as below) nor by the
> client (as in JS prototypal inheritance). I say "superset" because it also
> provides
> 4) an understandable alternative to multiple inheritance: symmetric traits
> composition with explicit conflict resolution.
> TraitsJS also has the same problems that presently deter people from using
> objects-as-closures:
> 5) Without VM support, it costs at least an allocation per method per
> instance, making it much too expensive. (See micro benchmarks in
> <http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en/us/pubs/archive/37485.pdf>.)
> 6) It is observably different than simply being sugar for JS's prototypal
> inheritance, introducing a non-uniformity when linked with libraries
> using prototypal inheritance.
> I think I am satisfied at this point that "prototypes as classes" has made a
> plausible enough start on addressing point #6 in its own way, without
> introducing an explicitly class-like abstraction, that we may not need
> classes-as-sugar for prototypal inheritance. This leaves #5 as *the*
> pressing problem for use of either safe pattern: objects-as-closures (as
> below) or traits (as in traitsjs or possibly eventually class-like sugar for
> them as previously proposed).
> My previous proposal for class-like sugar for traits composition was not
> popular. Whereas, in the absence of problem #5, I suspect the traitsjs
> library would be. As previously observed on this list, traitsjs is more
> JavaScripty. Ideal would be for JSVMs to magically make traitsjs efficient
> without requiring any language changes. If this is infeasible, perhaps we
> should instead be looking for the minimal language change that would enable
> a revision of traitsjs to run efficiently on ES-nest-next JSVMs.
> I say ES-next-next because it is too late to consider any such language
> change for ES-next. However, implementation experiments need not wait.
>
> On Thu, Nov 10, 2011 at 7:19 AM, Andreas Rossberg <rossberg at google.com>
> wrote:
> [...]
>>
>> No, that's how it works right now. The alternative is to lexically
>> close all methods over self at construction time:
>>
>>  function Point(x, y) {
>>    var self = this
>>    self.x = x
>>    self.y = y
>>    self.move = function(dx, dy) { self.x += dx; self.dy += dy }
>>  }
>>
>>  function ColorPoint(x, y, color) {
>>    var self = this
>>    Point.call(self, x, y)
>>    self.color = color
>>    self.recolor = function(c) { self.color = c }
>>  }
>>
>> As said, this doesn't play well with prototype inheritance. You have
>> to put all methods that refer to self on the object itself. But "inner
>> constructors" are straighforward and safe.
>
> --
>     Cheers,
>     --MarkM
>


More information about the es-discuss mailing list