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

Mark S. Miller erights at google.com
Thu Nov 10 07:59:07 PST 2011


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20111110/cfcfaac4/attachment-0001.html>


More information about the es-discuss mailing list