Making "super" work outside a literal?

Brendan Eich brendan at mozilla.com
Sat Jun 25 14:03:03 PDT 2011


CoffeeScript demo:

host-2-189:coffee-script brendaneich$ cat /tmp/super.coffee
class B
  constructor: (x) ->
    @x = x
  m: (z) ->
    @x = z * z

class D extends B
  constructor: (x, y) ->
    super x
    @y = y
  m: (z) ->
    1 + super z

d = new D(3, 4)
console.log d.m(5)
f = d.m
console.log f(6)
o = {m:f}
console.log o.m(7)

host-2-189:coffee-script brendaneich$ ./bin/coffee -p /tmp/super.coffee
(function() {
  var B, D, d, f, o;
  var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) {
    for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; }
    function ctor() { this.constructor = child; }
    ctor.prototype = parent.prototype;
    child.prototype = new ctor;
    child.__super__ = parent.prototype;
    return child;
  };
  B = (function() {
    function B(x) {
      this.x = x;
    }
    B.prototype.m = function(z) {
      return this.x = z * z;
    };
    return B;
  })();
  D = (function() {
    __extends(D, B);
    function D(x, y) {
      D.__super__.constructor.call(this, x);
      this.y = y;
    }
    D.prototype.m = function(z) {
      return 1 + D.__super__.m.call(this, z);
    };
    return D;
  })();
  d = new D(3, 4);
  console.log(d.m(5));
  f = d.m;
  console.log(f(6));
  o = {
    m: f
  };
  console.log(o.m(7));
}).call(this);


Note how references to lexically-bound closure function D are captured by the methods that use D.__super__. This is equivalent to Allen's proposal. Here's the program's output:

host-2-189:coffee-script brendaneich$ ./bin/coffee /tmp/super.coffee
26
37
50

Extracting f = d.m and reparenting f as o.m, calling either f() or o.m(), doesn't change anything.

/be

On Jun 25, 2011, at 1:49 PM, Brendan Eich wrote:

> On Jun 25, 2011, at 11:13 AM, Axel Rauschmayer wrote:
> 
>> I don’t know if this has been discussed, but I find the |super| work-around provided by YUI and CoffeeScript (in the generated code) not that bad:
>> 
>>       ThisClass.__super__.foo.call(this, arg1, arg2);
> 
> I'm not sure what you mean. If we add 'super', surely we want more than the __super__ hack. We also want a callable expression 'super' in constructors, and a 'super.foo' form for method and other property accesses from subclass methods. We don't want people writing out .call by hand.
> 
> 
>> With ThisClass.__super__ pointing to SuperClass.prototype.
> 
> The CoffeeScript compiler can lexically bind ThisClass and wire up __super__ with generated runtime helper code. That's all backstage of the CoffeeScript *language*, though.
> 
> 
>> As a completely static solution, one could maybe expand a super-call
>>       super.bar(x, y);
>> to
>>       __CurrentObject__.[[Prototype]].bar.call(this, x, y);
>> 
>> On the other hand, I don’t know if a reference to __CurrentObject__ is ever available for some kind of static expansion.
> 
> Are you talking about |here| again, with a new name? There is no static counterpart other than the one Allen proposed, the object literal directly containing the method that uses 'super'.
> 
> /be
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20110625/89d98f42/attachment.html>


More information about the es-discuss mailing list