On Nov 1, 2011, at 6:53 AM, Jeremy Ashkenas wrote:

> This doesn't sound right to me. What happens if you call the same method on 
> another object while the super-resolution is still active for the first call? 
> IOW, this sounds like it has similar problems to dynamic scope; the behavior 
> of a function becomes sensitive to the context in which it's called, which is 
> unmodular.
> 
> The problem isn't so much whether it's possible to come up with a semantics 
> by changing the runtime; I'm sure we could do that. The problem is finding a 
> way to get the semantics you want without taxing the performance all other 
> function calls in the language. (Also known as a "pay-as-you-go" feature: if 
> you don't use the feature, it shouldn't cost you anything.) We don't know how 
> to do that for super().
> 
> I think one piece of this is worth reiterating: As long as JS.next classes 
> are mostly sugar for prototypes, and prototypes aren't going to be deprecated 
> or removed in the next version of JavaScript (two propositions that I think 
> most of us can get behind) ... then it's very important that super() and new 
> class syntax *aren't* coupled. An ES6 super() that fails to work at all with 
> regular prototypes would be a serious problem. It would make interoperating 
> between vanilla prototypes and prototypes-built-by-classes much more 
> difficult than necessary, and the feel of the language as a whole much more 
> fragmented.

Jeremy, have  you looked at the current super proposal at 
http://wiki.ecmascript.org/doku.php?id=harmony:object_initialiser_super 

It does not couple super use with classes at all.  It does make it easy to 
define a super referencing method in an object or class literal, but the 
mechanism of super can be applied to any method defined in any object. 

You are creating confusion by suggesting that the proposed ES6 super support 
"fails to work at all with regular prototypes".

> 
> If you agree, then a super() that resolves dynamically is the way forward, 
> and things get easier: super() can be added without classes, classes can be 
> added without super(), and if both make it in, both can work seamlessly 
> together.

I absolutely agree with your requirement and absolutely disagree with your 
conclusion regarding "dynamic" super.

The complication of super is that each "super call" requires two independent 
pieces of state in additional to the method arguments: the object that will be 
used as the |this| value of the resulting method invocation and the object 
where property lookup will begin when searching for the  method. Let's call 
this the "lookup-point".   |super| when used to access a method property really 
represents a pair of values (this,lookup-point).  In the general case, these 
are not the same value so they must be independently captured and represented.

Where do these two pieces of state come from?  The |this| value of a super call 
is simply the |this| that was dynamically passed into the calling method.  
Where does the look-up point come from.  There are fundamentally two 
possibilities:

a) it is dynamically passed to every method invocation, ;just like |this| 
currently is
b) it is statically associated with the method in some way.

Each of these approach has some undesirable characteristics. 

a) requires that an extra implicit argument must be passed to every method 
invocation.  The value of this argument is the object from which the method was 
retrieved as an own property. This extra argument must be passed on every call 
because in general the call site does not know whether or not the callee 
references |super| so it must assume that it does. "Most" method calls take a 
single argument plus the implicit |this| argument (the actual argument 
statistics vary somewhat among languages but this is a good rule of thumb 
approximation for all OO languages including JS) so adding an additional 
lookup-point implicit argument is increasing the argument passing overhead of 
most calls by 50% yet super is only actually used by a single digit percentage 
of methods.  Also note that after inline caching has been applied, that 
argument passing is a major part of the total overhead of a call.  So, approach 
a) will have a negative performance impact on all calls for all programs.

b) static associates with each method a reference to it's lookup-poimt.  This 
association is made when the method is "installed" in an object.  This 
installation can occur syntactically, for example by defining a method as part 
of an object literal.  It can occur dynamically, for example, via the 
Object.defineMethod function in the ES6 proposal.  The advantage of this 
approach is that impose no overhead on method calls.  It is complete 
pay-as-you-go.  The disadvantage is that super-referencing methods be bound to 
a specific object.  If you want to copy the method  to a different object you 
have to copy the method and rebind it. Otherwise the method will remain 
statically bound to its original "home" object.

All modern OO languages that I am aware of have taken path b).  This includes 
highly dynamic prototypal languages such as self.  This is also the decision 
that was made when TC39 discussed this issue.  b) is simply the best compromise 
to a set of conflicting goals. 

Just saying "I don't think that an efficient, pay-as-you-go dynamic super() 
will be easy, but with the technical chops of TC39 at your disposal, it should 
be possible" is not helpful, particular when you make other statement that 
suggest that you really don't understand all the semantic subtitles of super. I 
hate to cite "authority" but the semantics and implementation alternatives of 
super  has been thoroughly explored over 30+ years by object-oriented language 
designer and implementer including myself.  This is not a new problem, the 
"technical chops" have already been supplied.  A unique new solution that no 
one has ever though of before would be welcomed.  If you have such a solution, 
please put it forward.  But don't assume that it is something that has not 
already been deeperly consider both by TC39 member and other language designers.

Allen



_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to