On Mon, Oct 31, 2011 at 11:11 PM, David Herman <dher...@mozilla.com> wrote:

>
> But IIUC, you're proposing a semantics where you construct a brand new
> object P whose __proto__ is SuperClass.prototype and then copy all the
> own-properties of the RHS into P.
>

Not quite. P is a constructor function (class object), SuperClass is a
constructor function. Unless I'm confused, P's ".prototype" is an instance
of SuperClass, and therefore instances of P have an RHS own-property-filled
__proto__ object that itself has a __proto__ object pointing at
SuperClass.prototype. Fun stuff.

I wish it were possible, but Allen has convinced me that you can't make
> super work via a purely dynamic definition. It has to be hard-wired to the
> context in which it was created. Let me see if I can make the argument
> concisely.
>
> Semantics #1: super(...args) ~=~
> this.__proto__.METHODNAME.call(this.__proto__, ...args)
>
> This semantics is just wrong. You want to preserve the same |this| as you
> move up the chain of super calls, so that all this-references get the most
> derived version of all other properties.
>
> Semantics #2: super(...args) ~=~ this.__proto__.METHODNAME.call(this,
> ...args)
>
> This semantics is just wrong. It correctly preserves the most derived
> |this|, but if it tries to continue going up the super chain, it'll start
> right back from the bottom; you'll get an infinite recursion of the first
> super object's version of the method calling itself over and over again.
>
> Semantics #3: super(...args) ~=~
> this.__proto__.METHODNAME.callForSuper(this, this.__proto__, ...args)
>
> This semantics introduces a new implicit "where did I leave off in the
> super chain?" argument into the call semantics for every function in the
> language. It's sort of the "correct" dynamic semantics, but it introduces
> an unacceptable cost to the language. JS engine implementors will not
> accept it.
>
> Semantics #4: super(...args) ~=~ LEXICALLYBOUNDPROTO.call(this, ...args)
>

Indeed, super() is tricky. For what it's worth, CoffeeScript's class syntax
requires literal (non-expression) class body definitions in part to make
Semantics #4 possible, with purely lexical super calls. Your example's
"LEXICALLYBOUNDPROTO" is CoffeeScript's "ClassObject.__super__".

Fortunately, y'all have the ability to bend the runtime to your will. To
solve the super() problem, you can simply have the JavaScript engine keep
track of when a function has called through the `super()` boundary, and
from that point on downwards in that method's future call stack, add an
extra `__proto__` lookup to each super resolution. When the inner `super()`
is then called in the context of the outer `this`, the result will be a
variant of #2:

this.__proto__.__proto__.METHODNAME.call(this, ...args)

... and it should work.

There may be something wrong with the above -- but dynamic super() should
be a solveable problem for JS.next, even if not entirely desugar-able into
ES3 terms.
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to