Minimalist Classes

Dmitry Soshnikov dmitry.soshnikov at gmail.com
Tue Nov 1 12:57:04 PDT 2011


On 01.11.2011 22:53, Axel Rauschmayer wrote:
>> Can you show an example (and also the same example which is solved by es-proposed super-calls)?
>>
>> The technique I showed of course initially is designed to be used with class-system; though, I think it can be adopted to class-free system as well.
>
>
> Code taken from https://gist.github.com/1330574#L68
>
> Object.defineProperty(Object.prototype, "super", {
>    value: function (method) {
>      let proto = Object.getPrototypeOf(this);
>
>      // we should use exactly this link and not
>      // proto.__proto__ i.e. Object.getPrototypeOf(proto)
>      // since in other case we can go away to i-looping
>      let parentProto = proto.__parentProto__;
>
>      // remove "__parentProto__" property from
>      // our prototype to avoid i-looping; at 3rd and
>      // later levels the property will be found just deeper
>      delete proto.__parentProto__;
>
>      // call the parent method
>      parentProto[method].apply(this, [].slice.call(arguments, 1));
>
>      // and restore "__parentProto__" back
>      Object.defineProperty(proto, "__parentProto__", {
>        value: parentProto,
>        writable: true,
>        configurable: true
>      });
>    }
> });
>
> Two more comments:
>
> - The code does not work if an instance method makes a super-call.
>

Yep, and the reason is still the same -- the lib initially was designed 
to work in border of classes and covers most of cases (excluding 
subtle). Perhaps it can be adjusted to support super calls from instance 
method.

Anyway, that's said, I showed it only to refer the issue which basically 
isn't a (big) issue and can be solved even with a library -- of course 
in borders of some aspect -- in particular -- with using classes, not 
class-free super-calls with subtle cases.

Though, the thread is moved to discussion of class-free super-calls, 
meanwhile it's still good to understand which easy (and *syntactically* 
easy!) solution we may have for classes in ES.

> - No matter where you are in a prototype chain, you will always delete and restore __parentProto__ in the second chain member (in the prototype of |this|). Have you tested it with more than two recursive super-calls?
>

Nope, I didn't tested; you may send me an example though, it will be 
helpful.

> What might work is something like the following:
>
> When you look for super.foo(), traverse the prototype chain, starting at |this|. Look for the *second* occurrence of "foo". Record the object where you have found it in this["obj_of_super_"+"foo"] (which you delete after the super-call returns). In subsequent super-calls, you can start your search at this.obj_of_super_foo (instead of |this|).
>
> The above effectively records where a method has been found, but does it more indirectly (and waits until super has been called).
>

Yes, it's also can be a solution. My solution is just "one-of". As you 
saw, I used other solutions for this -- mostly with using `caller` and 
statically saving the method name (which is OK for SpiderMonkey which 
has `name` property for functions).

> However, this still fails when one of the super.foo() starts to call this.foo() (which is perfectly OK if there are parameters involved that prevent an infinite recursion).
>

It's also a tricky case. I would even say -- "an error in programming 
logic". In static language I guess you expect that this.foo() then calls 
foo of the super (current) class but not goes again from the instance, 
right? Don't know, it's really a subtle case, I didn't encounter it in 
practical programming, though I agree that the case should be considered 
when designing a language.

Dmitry.


More information about the es-discuss mailing list