Making "super" work outside a literal?

Brendan Eich brendan at mozilla.com
Wed Jun 22 08:01:17 PDT 2011


On Jun 22, 2011, at 6:48 AM, Sean Eagan wrote:

> There is no infinite recursion hazard in the semantics that Axel
> suggested, ...

Yes, I acknowledged that, but went on to repeat that an extra implicit parameter is too costly (as opposed to a new internal property of functions).


> I don't think we need any "safety check" when assigning a method or
> accessor getter or setter that uses super to an object.  The concept
> of "super" seems to be a relative one,

That is what we are arguing about. It's not a conclusion we all share.


> it is the object one step up in
> the prototype chain from the current object.

The "current object" -- Axel's |here| -- is not exposed in JS. Exposing it requires another implicit parameter, which costs too much.


>  If a method or accessor
> getter or setter needs an *absolute* reference to the prototype of a
> given object, it should refer to it by name.

Agreed, especially when mutating. Bu the relativity of |super| is still in dispute (relative to what? when?).


> Also, AFAICT there is no performance cost of a dynamic super beyond
> the performance cost of static super.

No, see above.


> If there would be any
> difference between the two, it would be in the work that needs to be
> done to determine what the |super| binding of a particular call site
> should be.  In either the dynamic or static case, the engine will
> climb the prototype chain when looking for a method or accessor
> property.  When it finds one that matches, in the dynamic case the
> |super| binding will just be the [[Prototype]] internal property of
> the current prototype chain object,

And that must be passed as an extra implicit parameter, as is done with |this|.


> in the static case it will be the
> [[???]] internal property of the method or accessor getter or setter
> found.

The [[Super]] property, let's say. Note how this is static indeed, set at function creation time. It is not set on each call. It is not a parameter passed by mutating the function on each call.


> Thus, in both cases it will just be a matter of accessing an
> internal property of an object that is immediately accessible when
> climbing the prototype chain.

Here you seem to assume the |here| result found during callee-expression evaluation in your proposal can be stored in [[Super]]. That's still an implicit per-call parameter (an even less efficient way to pass it, by side-effecting the called function object, but never mind!). The problem is the per-call overhead.

/be


> 
> On Tue, Jun 21, 2011 at 3:55 PM, Brendan Eich <brendan at mozilla.com> wrote:
>> On Jun 21, 2011, at 11:53 AM, Brendan Eich wrote:
>> 
>> On Jun 21, 2011, at 11:33 AM, Oliver Hunt wrote:
>> 
>> I'm answering some of the performance questions in this, but i don't know
>> what the intended semantics of 'dynamic super' would be so I can't give
>> specific details of most of the use cases.  If it's essentially sugar for
>> super.foo => Object.getPrototypeOf(this).foo (with appropriate munging for
>> calls, etc) then the cost is at point of use only, but if it's anything more
>> fun (there are references to additional implicit parameters below which
>> would be fairly bad for performance of calls)
>> 
>> That's the point: super must mean something other than
>> Object.getPrototypeOf(this). Otherwise with the prototypal pattern you will
>> infinitely recurse calling the same prototype-homed foo from foo via
>> super.foo().
>> 
>> Example:
>> C.prototype = {
>>   foo() { addedValue(); return super.foo(); }
>>   ...
>> };
>> x = new C;
>> x.foo();   // oops, diverges in endless self-recursion.
>> 
>> Now, with the static 'super' semantics plus Object.defineMethod(O, 'foo',
>> C.prototype.foo), you can rebind 'super'.
>> One thing I'm not sure about: whether Object.defineMethod should mutate
>> C.prototype.foo's internal property, or make a new function object with a
>> different 'super' binding.
>> In any case, the static and internal-to-method semantics avoid the infinite
>> recursion hazard, and they avoid the cost of an extra parameter beyond
>> |this|.
>> /be
>> _______________________________________________
>> es-discuss mailing list
>> es-discuss at mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>> 
>> 
> 
> Cheers,
> Sean Eagan



More information about the es-discuss mailing list