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