Re: The `super` keyword doesn't work as it should?

2016-07-19 Thread Bergi

Raul-Sebastian Mihăilă wrote:

An alternative would be to consider the object where the method key was
found as the home object of the method.


That's just as error-prone, method borrowing would only work when the 
two objects had the same superclass.
Also, what about methods that are not "found" anywhere when called, for 
example when used with `call`/`apply`/`bind`? Or static class methods 
that don't use `this` at all and are called like a plain function?


Are you suggesting that every property access that yields a function 
implicitly creates a closure over the "home"/"found" object? That's a 
no-no for obvious reasons.


Kind regards,
 Bergi
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: The `super` keyword doesn't work as it should?

2016-07-19 Thread Allen Wirfs-Brock

> On Jul 19, 2016, at 11:45 AM, Raul-Sebastian Mihăilă  
> wrote:
> 
> An alternative would be to consider the object where the method key was found 
> as the home object of the method.

that was considered while designing ES6.  The problem is that it introduces an 
additional implicit parameter (or equivalent overhead) for every method call, 
regardless of whether or not it is actually needed by the  invoked method.

Allen

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: The `super` keyword doesn't work as it should?

2016-07-19 Thread Raul-Sebastian Mihăilă
An alternative would be to consider the object where the method key was
found as the home object of the method.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: The `super` keyword doesn't work as it should?

2016-07-19 Thread Logan Smyth
Joe, it seems like you've focused on `super ===
Object.getPrototypeOf(this)` as the overall ideal without considering the
issues with it. I've tried to put together a few counterexamples below. Say
you have a base set up like this:

```
var a = {
  prop: null,
  method(){
this.prop = 4;

// super.method();
// vs
// Object.getPrototypeOf(this).method.call(this);

return this.prop;
  },
};
var b = {
  __proto__: a,
  method: function(){
this.prop = 5;

// super.method();
// vs
// Object.getPrototypeOf(this).method.call(this);
  },
};
var c = {
__proto__: b,
method: function(){
this.prop = 6;
},
};
```

In this example, `super.method()` will work fine, and `a.method() === 6`
because each super call will reassign `this.prop`, where `this === a`.

`Object.getPrototypeOf(this)` has one main core issue here, which is that
we are doing `.call(this);`, meaning that when `a.method()` is called and
subsequently calls `b.method`, `this === a`, not `this === b` inside
`b.method`. This means that when `b` attempts to call _its_ super class, it
has no way of finding `c`, because `this === a` and
`Object.getProtoypeOf(this) === b`, not `c`. This leads to the infinite
recursion case that Bergi mentioned.

The only way for this to work, given your proposal, would be to call
`b.method` with `this === b` instead of `this === a`, e.g. `
Object.getPrototypeOf(this).method.call(Object.getPrototypeOf(this));`, but
that would mean that operations happening inside `b.method`, like the
`this.prop = 5;` would be assigning a property on the wrong object (`b`),
instead of the `a` object, leading to `a.method() === 4`.

ES6 solves this by looking up the parent prototype using the
`[[HomeObject]]` as the root instead of `this`, where `[[HomeObject]]` is
essentially the object that the function was attached to syntactically. The
issue is that a standalone function has no object that it is attached to.
This means that usage of `super.foo` ends up being restricted to only
functions written with method syntax, where they are attached clearly to a
specific object.

On Tue, Jul 19, 2016 at 3:13 AM, Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> `super === Object.getPrototypeOf(this)` also doesn't work with multiple
> inheritance.
>
> If interested, it has been solved dynamically in this good'ol library:
> https://github.com/WebReflection/es-class#es6-ready
>
> Regards
>
> On Tue, Jul 19, 2016 at 11:03 AM, /#!/JoePea  wrote:
>
>> Hi Bergi, yes, so the object that `super` references would work like
>> `this`, where the value is determined at runtime instead of in a
>> declaration. Basically, `super === Object.getPrototypeOf(this)` would
>> actually be true in my examples. It may be due to ["extra overhead"](
>> http://disq.us/p/1a56gxj) that `[[HomeObject]]` is only defined during
>> declaration, but that is at the huge expense of making the language less
>> intuitive and also more difficult to work with in some cases (for example,
>> in designing a multiple-inheritance scheme).
>>
>> It would simply be great for super to just work as expected in the
>> examples I gave, which would mean that super would work in tandem and
>> intuitively with the various ways in which we can create
>> objects-extending-objects in JS.
>>
>> Good news is that making the necessary change to `super` in ES8 or later
>> is completely backwards compatible with how it currently works.
>>
>> I wonder what the performance problems are and if they can be solved.
>>
>> */#!/*JoePea
>>
>> On Mon, Jul 18, 2016 at 2:46 PM, Bergi  wrote:
>>
>>> /#!/JoePea wrote:
>>>
>>> Why can't `super` simply be a shortcut
 for "look up the prototype of the object that the method is called on,
 then
 find the `.constructor` property and call it on `this`"? That seems to
 be
 simple.

>>>
>>> Simple, yes, and broken in the case of multi-level inheritance:
>>> ```
>>> const x = Object.assign(Object.create({
>>> method() {
>>> console.log("parent");
>>> }
>>> }), {
>>> method() {
>>> console.log("child");
>>> Object.getPrototypeOf(this).method(); // super.method()
>>> }
>>> });
>>> x.method(); // works as expected
>>>
>>> const y = Object.create(x);
>>> y.method(); // infinite loop/stack overflow
>>> ```
>>> A `super` query must not depend on `this` (only), it must statically
>>> resolve the object on which the called method is defined.
>>>
>>> In constructors, using the prototype of the currenctly called
>>> constructor for `super()` works well, but you'd need to use
>>> `Object.setPrototype` as there is currently no declarative way other than
>>> `class`es to define functions with custom prototypes.
>>>
>>> In methods, there would need to be a way to populate the [[HomeObject]]
>>> other than declaring the method as part of a class/object literal.
>>>
>>> Kind regards,
>>>  Bergi
>>> 

Re: The `super` keyword doesn't work as it should?

2016-07-19 Thread Andrea Giammarchi
`super === Object.getPrototypeOf(this)` also doesn't work with multiple
inheritance.

If interested, it has been solved dynamically in this good'ol library:
https://github.com/WebReflection/es-class#es6-ready

Regards

On Tue, Jul 19, 2016 at 11:03 AM, /#!/JoePea  wrote:

> Hi Bergi, yes, so the object that `super` references would work like
> `this`, where the value is determined at runtime instead of in a
> declaration. Basically, `super === Object.getPrototypeOf(this)` would
> actually be true in my examples. It may be due to ["extra overhead"](
> http://disq.us/p/1a56gxj) that `[[HomeObject]]` is only defined during
> declaration, but that is at the huge expense of making the language less
> intuitive and also more difficult to work with in some cases (for example,
> in designing a multiple-inheritance scheme).
>
> It would simply be great for super to just work as expected in the
> examples I gave, which would mean that super would work in tandem and
> intuitively with the various ways in which we can create
> objects-extending-objects in JS.
>
> Good news is that making the necessary change to `super` in ES8 or later
> is completely backwards compatible with how it currently works.
>
> I wonder what the performance problems are and if they can be solved.
>
> */#!/*JoePea
>
> On Mon, Jul 18, 2016 at 2:46 PM, Bergi  wrote:
>
>> /#!/JoePea wrote:
>>
>> Why can't `super` simply be a shortcut
>>> for "look up the prototype of the object that the method is called on,
>>> then
>>> find the `.constructor` property and call it on `this`"? That seems to be
>>> simple.
>>>
>>
>> Simple, yes, and broken in the case of multi-level inheritance:
>> ```
>> const x = Object.assign(Object.create({
>> method() {
>> console.log("parent");
>> }
>> }), {
>> method() {
>> console.log("child");
>> Object.getPrototypeOf(this).method(); // super.method()
>> }
>> });
>> x.method(); // works as expected
>>
>> const y = Object.create(x);
>> y.method(); // infinite loop/stack overflow
>> ```
>> A `super` query must not depend on `this` (only), it must statically
>> resolve the object on which the called method is defined.
>>
>> In constructors, using the prototype of the currenctly called constructor
>> for `super()` works well, but you'd need to use `Object.setPrototype` as
>> there is currently no declarative way other than `class`es to define
>> functions with custom prototypes.
>>
>> In methods, there would need to be a way to populate the [[HomeObject]]
>> other than declaring the method as part of a class/object literal.
>>
>> Kind regards,
>>  Bergi
>> ___
>> es-discuss mailing list
>> es-discuss@mozilla.org
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: The `super` keyword doesn't work as it should?

2016-07-19 Thread /#!/JoePea
Hi Bergi, yes, so the object that `super` references would work like
`this`, where the value is determined at runtime instead of in a
declaration. Basically, `super === Object.getPrototypeOf(this)` would
actually be true in my examples. It may be due to ["extra overhead"](
http://disq.us/p/1a56gxj) that `[[HomeObject]]` is only defined during
declaration, but that is at the huge expense of making the language less
intuitive and also more difficult to work with in some cases (for example,
in designing a multiple-inheritance scheme).

It would simply be great for super to just work as expected in the examples
I gave, which would mean that super would work in tandem and intuitively
with the various ways in which we can create objects-extending-objects in
JS.

Good news is that making the necessary change to `super` in ES8 or later is
completely backwards compatible with how it currently works.

I wonder what the performance problems are and if they can be solved.

*/#!/*JoePea

On Mon, Jul 18, 2016 at 2:46 PM, Bergi  wrote:

> /#!/JoePea wrote:
>
> Why can't `super` simply be a shortcut
>> for "look up the prototype of the object that the method is called on,
>> then
>> find the `.constructor` property and call it on `this`"? That seems to be
>> simple.
>>
>
> Simple, yes, and broken in the case of multi-level inheritance:
> ```
> const x = Object.assign(Object.create({
> method() {
> console.log("parent");
> }
> }), {
> method() {
> console.log("child");
> Object.getPrototypeOf(this).method(); // super.method()
> }
> });
> x.method(); // works as expected
>
> const y = Object.create(x);
> y.method(); // infinite loop/stack overflow
> ```
> A `super` query must not depend on `this` (only), it must statically
> resolve the object on which the called method is defined.
>
> In constructors, using the prototype of the currenctly called constructor
> for `super()` works well, but you'd need to use `Object.setPrototype` as
> there is currently no declarative way other than `class`es to define
> functions with custom prototypes.
>
> In methods, there would need to be a way to populate the [[HomeObject]]
> other than declaring the method as part of a class/object literal.
>
> Kind regards,
>  Bergi
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss