new instantiation design alternatives

classic Classic list List threaded Threaded
136 messages Options
1234 ... 7
Reply | Threaded
Open this post in threaded view
|

new instantiation design alternatives

Allen Wirfs-Brock
At the last TC39 meeting ( https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-07/jul-30.md#44-instantiation-reform-review-create-design-rationale-and-possible-alternatives and https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-07/jul-31.md#44-follow-up-instantiation-reform-create ) we agreed to a general direction to try for a new object instantiation design to replace @@create. 

Since then I have gotten feedback and had design discussions with a number of individuals. This has lead to a number of refinements of the core design and one remaining point where there are strong contrary positions. The point of contention is about whether or not a subclass construction ever implicitly calls its superclass constructor.

https://gist.github.com/allenwb/291035fbf910eab8e9a6  summaries the  main syntactic changes since the meeting and provides rationales them. These features are common  to both alternates.  this is a good place to start, after reading the meeting notes. 

I have prepared two longer Gists that outline the two alternatives designs, presents design rationales,  and provides usage examples for a number of likely use cases. Note that  there is more commonalities then differences among the two alternatives.  the syntactic choices and semantics of [[Construct]] are the same for both. 

These two Gist have parallel construction for easy comparison. I suggest approaching this is by first readying through one of the Gists and then doing a side by side read through of the alternative to see the differences in the designs and usage.

https://gist.github.com/allenwb/5160d109e33db8253b62 with implicit super construct if no local allocation
https://gist.github.com/allenwb/53927e46b31564168a1d explicit super construct required if no local allocation

I appreciate it if major constructive feedback on any of these documents were made via Gist comments. 

Allen

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: new instantiation design alternatives

Boris Zbarsky
On 9/11/14, 12:35 PM, Allen Wirfs-Brock wrote:
> https://gist.github.com/allenwb/291035fbf910eab8e9a6  summaries the
>   main syntactic changes since the meeting and provides rationales them.
> These features are common  to both alternates.  this is a good place to
> start, after reading the meeting notes.

Allen, thanks for putting this together!

I have a question: what do the uses of "this^" in this document mean?
Are those meant to be "new^"?

-Boris
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: new instantiation design alternatives

Allen Wirfs-Brock
oh oops!  they are supposed to be "new^".  Will fix...

On Sep 11, 2014, at 12:55 PM, Boris Zbarsky wrote:

> On 9/11/14, 12:35 PM, Allen Wirfs-Brock wrote:
>> https://gist.github.com/allenwb/291035fbf910eab8e9a6  summaries the
>>  main syntactic changes since the meeting and provides rationales them.
>> These features are common  to both alternates.  this is a good place to
>> start, after reading the meeting notes.
>
> Allen, thanks for putting this together!
>
> I have a question: what do the uses of "this^" in this document mean? Are those meant to be "new^"?
>
> -Boris
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: new instantiation design alternatives

Jason Orendorff
It seems like new^ is a new argument that is implicitly passed to all functions.

What does new^ mean in an arrow function?

How does new^ interact with a proxy whose target is a constructor?

-j


On Thu, Sep 11, 2014 at 3:00 PM, Allen Wirfs-Brock
<[hidden email]> wrote:

> oh oops!  they are supposed to be "new^".  Will fix...
>
> On Sep 11, 2014, at 12:55 PM, Boris Zbarsky wrote:
>
>> On 9/11/14, 12:35 PM, Allen Wirfs-Brock wrote:
>>> https://gist.github.com/allenwb/291035fbf910eab8e9a6  summaries the
>>>  main syntactic changes since the meeting and provides rationales them.
>>> These features are common  to both alternates.  this is a good place to
>>> start, after reading the meeting notes.
>>
>> Allen, thanks for putting this together!
>>
>> I have a question: what do the uses of "this^" in this document mean? Are those meant to be "new^"?
>>
>> -Boris
>> _______________________________________________
>> es-discuss mailing list
>> [hidden email]
>> https://mail.mozilla.org/listinfo/es-discuss
>>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: new instantiation design alternatives

Jason Orendorff
I meant to add: I think it's *great* that we're still iterating on
this. Surely there's a way.

On Thu, Sep 11, 2014 at 3:37 PM, Jason Orendorff
<[hidden email]> wrote:

> It seems like new^ is a new argument that is implicitly passed to all functions.
>
> What does new^ mean in an arrow function?
>
> How does new^ interact with a proxy whose target is a constructor?
>
> -j
>
>
> On Thu, Sep 11, 2014 at 3:00 PM, Allen Wirfs-Brock
> <[hidden email]> wrote:
>> oh oops!  they are supposed to be "new^".  Will fix...
>>
>> On Sep 11, 2014, at 12:55 PM, Boris Zbarsky wrote:
>>
>>> On 9/11/14, 12:35 PM, Allen Wirfs-Brock wrote:
>>>> https://gist.github.com/allenwb/291035fbf910eab8e9a6  summaries the
>>>>  main syntactic changes since the meeting and provides rationales them.
>>>> These features are common  to both alternates.  this is a good place to
>>>> start, after reading the meeting notes.
>>>
>>> Allen, thanks for putting this together!
>>>
>>> I have a question: what do the uses of "this^" in this document mean? Are those meant to be "new^"?
>>>
>>> -Boris
>>> _______________________________________________
>>> es-discuss mailing list
>>> [hidden email]
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>>
>> _______________________________________________
>> es-discuss mailing list
>> [hidden email]
>> https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: new instantiation design alternatives

Allen Wirfs-Brock
In reply to this post by Jason Orendorff

On Sep 11, 2014, at 1:37 PM, Jason Orendorff wrote:

It seems like new^ is a new argument that is implicitly passed to all functions.

What does new^ mean in an arrow function?

How does new^ interact with a proxy whose target is a constructor?


`new^`  has the value of the receiver argument to the [[Construct[[ internal method. This is a parameter newly added to [[Construct]].  Normally it is set to the the value that `new` is applied to.  But for `new super` calls it is set to the current `new^` value. In that regard it is like the "receiver" parameter to [[Get]] and [[Set]]. If a constructor is invoked via [[Call]]  `new^` has the value `undefined`.  that's how you can test for "called as a function" vs. "called as a constructor".

`new^` is lexically scoped, just this `this` and `super`.  If an arrow function references `new^` it is the value of the closest lexically enclosing constructor function (a function that implements [[Construct]]).

Just like [[Get]] and [[Set]], the trap for [[Construct]] is extended to include a "receiver" parameter.

Allen







-j


On Thu, Sep 11, 2014 at 3:00 PM, Allen Wirfs-Brock
<[hidden email]> wrote:
oh oops!  they are supposed to be "new^".  Will fix...

On Sep 11, 2014, at 12:55 PM, Boris Zbarsky wrote:

On 9/11/14, 12:35 PM, Allen Wirfs-Brock wrote:
https://gist.github.com/allenwb/291035fbf910eab8e9a6  summaries the
main syntactic changes since the meeting and provides rationales them.
These features are common  to both alternates.  this is a good place to
start, after reading the meeting notes.

Allen, thanks for putting this together!

I have a question: what do the uses of "this^" in this document mean? Are those meant to be "new^"?

-Boris
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: new instantiation design alternatives

Brendan Eich-2
Ob. bikeshed: why not `new?` as the magic pair of tokens? Seems
unambiguous given `new` as a reserved identifier since dayone.

/be
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: new instantiation design alternatives

Allen Wirfs-Brock

On Sep 11, 2014, at 3:03 PM, Brendan Eich wrote:

> Ob. bikeshed: why not `new?` as the magic pair of tokens? Seems unambiguous given `new` as a reserved identifier since dayone.
>
> /be
>

"new?" would be fine,.  Actually better.  But we shied away from it, so as to not impinge upon future use of "?".  Even if there was no lexical ambiguity there might be conceptual confusion with some future usage.

But, if there is a general willingness to to use "?", I'd be all for it.

BTW, "new^" (other whatever) is intended to be a single token, not a pair of tokens.

Allen
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: new instantiation design alternatives

Claude Pache
In reply to this post by Brendan Eich-2

Le 12 sept. 2014 à 00:03, Brendan Eich <[hidden email]> a écrit :

> Ob. bikeshed: why not `new?` as the magic pair of tokens? Seems unambiguous given `new` as a reserved identifier since dayone.

If one day we introduce the so-called existential operator `foo?.bar`, it will be quite confusing to already have `new?.constructor` for something else.

—Claude
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: new instantiation design alternatives

Brendan Eich-2
In reply to this post by Allen Wirfs-Brock
Allen Wirfs-Brock wrote:
> "new?" would be fine,.  Actually better.  But we shied away from it, so as to not impinge upon future use of "?".  Even if there was no lexical ambiguity there might be conceptual confusion with some future usage.

When last we considered refutable patterns, e.g., match (e) { case {x,
y, ?z}: /* x and y, maybe z */ }, the ? came in front and was in the
pattern language -- a new and different sub-grammar.

What other possible future ? uses were there?

> But, if there is a general willingness to to use "?", I'd be all for it.
>
> BTW, "new^" (other whatever) is intended to be a single token, not a pair of tokens.

+1 to 1 token.

/be
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: new instantiation design alternatives

Brendan Eich-2
In reply to this post by Claude Pache
Claude Pache wrote:
> Le 12 sept. 2014 à 00:03, Brendan Eich<[hidden email]>  a écrit :
>
>> >  Ob. bikeshed: why not `new?` as the magic pair of tokens? Seems unambiguous given `new` as a reserved identifier since dayone.
>
> If one day we introduce the so-called existential operator `foo?.bar`, it will be quite confusing to already have `new?.constructor` for something else.

Hah, I should have read ahead. You're right we were considering foo?.bar
here:

http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator

I wrote that and championed it. But I probably forgot about it ten
minutes ago when replying to Allen, because it seemed to fail for good
at past TC39 meetings:

http://esdiscuss.org/topic/sept-18-tc39-meeting-notes#content-2

(search for "non-starter").

Then you rallied in this thread:

http://esdiscuss.org/topic/the-existential-operator

but it still didn't end well.

/be
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: new instantiation design alternatives

Jeff Morrison
In reply to this post by Allen Wirfs-Brock
" If a constructor body contains an assignment of the form this = then automatic allocation is not performed and the constructor is expected to perform manual allocation."
If I'm understanding this correctly, this means that snippet (A) would never have access to `this`, but snippet (B) would have an implicit `this` binding -- is that correct?

(A)
```

class Foo extends Bar {
  constructor() {
    if (false) {
      this = super();
    }
    this; // undefined
  }
}
```


(B)
```

class Foo extends Bar {
  constructor() {
    // No call to `this =` present in the constructor
    this; // the automatically allocated object -- i.e. this !== undefined
  }
}
```


If this is the case, it occurs to me that it would raise issues for things like automated refactoring and/or dead code elimination (as a minifier might do).
Normally a minifier (or even a human) would expect to be able to eliminate the entire conditional altogether if they were confident the condition never evaluated to true. But with this static pre-check acting as the indicator for whether automatic allocation/binding should happen, doing so would cause the constructor to act very unexpectedly differently in the two cases.

I wish I could suggest an alternative, but nothing comes to mind right now.

Thoughts?

-Jeff

On 9/11/14, 12:35 PM, Allen Wirfs-Brock wrote:
At the last TC39 meeting ( https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-07/jul-30.md#44-instantiation-reform-review-create-design-rationale-and-possible-alternatives and https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-07/jul-31.md#44-follow-up-instantiation-reform-create ) we agreed to a general direction to try for a new object instantiation design to replace @@create. 

Since then I have gotten feedback and had design discussions with a number of individuals. This has lead to a number of refinements of the core design and one remaining point where there are strong contrary positions. The point of contention is about whether or not a subclass construction ever implicitly calls its superclass constructor.

https://gist.github.com/allenwb/291035fbf910eab8e9a6  summaries the  main syntactic changes since the meeting and provides rationales them. These features are common  to both alternates.  this is a good place to start, after reading the meeting notes. 

I have prepared two longer Gists that outline the two alternatives designs, presents design rationales,  and provides usage examples for a number of likely use cases. Note that  there is more commonalities then differences among the two alternatives.  the syntactic choices and semantics of [[Construct]] are the same for both. 

These two Gist have parallel construction for easy comparison. I suggest approaching this is by first readying through one of the Gists and then doing a side by side read through of the alternative to see the differences in the designs and usage.

https://gist.github.com/allenwb/5160d109e33db8253b62 with implicit super construct if no local allocation
https://gist.github.com/allenwb/53927e46b31564168a1d explicit super construct required if no local allocation

I appreciate it if major constructive feedback on any of these documents were made via Gist comments. 

Allen


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: new instantiation design alternatives

Claude Pache


Le 12 sept. 2014 à 08:39, Jeff Morrison <[hidden email]> a écrit :

" If a constructor body contains an assignment of the form this = then automatic allocation is not performed and the constructor is expected to perform manual allocation."
If I'm understanding this correctly, this means that snippet (A) would never have access to `this`, but snippet (B) would have an implicit `this` binding -- is that correct?

(A)
```

class Foo extends Bar {
  constructor() {
    if (false) {
      this = super();
    }
    this; // undefined
  }
}
```


(B)
```

class Foo extends Bar {
  constructor() {
    // No call to `this =` present in the constructor
    this; // the automatically allocated object -- i.e. this !== undefined
  }
}
```


If this is the case, it occurs to me that it would raise issues for things like automated refactoring and/or dead code elimination (as a minifier might do).
Normally a minifier (or even a human) would expect to be able to eliminate the entire conditional altogether if they were confident the condition never evaluated to true. But with this static pre-check acting as the indicator for whether automatic allocation/binding should happen, doing so would cause the constructor to act very unexpectedly differently in the two cases.

I wish I could suggest an alternative, but nothing comes to mind right now.

Thoughts?

So, let's explore how to cope with the design that consists to determine the automaticity of allocation/binding independently of the actual code of the constructor (as it was the case in my original design.) 

The rule must be the following one:

* For constructors in classes, automatic allocation occurs if and only if there is no `extends` clause.
* For constructors defined the ES1-5 way (outside classes), automatic allocation occurs.

That is satisfying for most cases while remaining backward compatible with ES1-5, but it is a priori problematic in the following situations, where one may want manual allocation whereas the rule mandates an automatic one.

(1) Base classes (i.e., classes without `extends` clause) that want manual allocation. The legacy possibility of returning an alien object from the constructor remains. Alternatively, the following hack is possible, provided that we accept `Function.prototype` as a constructor.

class Base extends Function.prototype { /* ... */  } 

(IIUC, the prototype chain for both constructor and instances will be the same as without the `extends Function.prototype` clause.) If that situation occurs often, we might want to provide sugar around that.

(2) Constructors defined outside classes that want manual allocation of `this`. For these, I propose the following syntax:

function Derived(a, b) extends Base { /* ... */ }

as an almost equivalent of:

function Derived(a, b) { /* ... */ }
Derived.__proto__ = Base
Derived.prototype = { __proto__: Base.prototype || Object.prototype, constructor: Derived }

except that the automatic allocation of `this` does not occurs in the former case. Like constructors defined in classes, the `extends Function.prototype` trick is possible.

—Claude


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

RE: new instantiation design alternatives

Domenic Denicola-2
In reply to this post by Brendan Eich-2
From: es-discuss [mailto:[hidden email]] On Behalf Of Brendan Eich

> Ob. bikeshed: why not `new?` as the magic pair of tokens? Seems unambiguous given `new` as a reserved identifier since dayone.

This reads really well for the `if (new?) { ... }` case, but poorly for the `this = Object.create(new?.prototype)` case.
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: new instantiation design alternatives

Kevin Smith
In reply to this post by Allen Wirfs-Brock
Thanks for this!

A question:  why is it important to provide this new functionality ("new^", "this = whatever") to basic constructors?  Why not use class syntax as an opt-in to these features?


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: new instantiation design alternatives

Claude Pache

Le 12 sept. 2014 à 15:19, Kevin Smith <[hidden email]> a écrit :

> Thanks for this!
>
> A question:  why is it important to provide this new functionality ("new^", "this = whatever") to basic constructors?  Why not use class syntax as an opt-in to these features?

ES classes are only syntax; the objects defined by that syntax are just regular functions. Basically, these functions could have been defined the traditional way and have their properties related to prototypal inheritance manually adjusted afterwards. It would be artificial to limit a feature based on *how* the objects were constructed.

—Claude
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: new instantiation design alternatives

Jeremy Martin
Sorry to interject, but was the rationale for needing a new syntax for this (vs. an API-based solution) presented anywhere? I can't seem to find it.

On Fri, Sep 12, 2014 at 10:23 AM, Claude Pache <[hidden email]> wrote:

Le 12 sept. 2014 à 15:19, Kevin Smith <[hidden email]> a écrit :

> Thanks for this!
>
> A question:  why is it important to provide this new functionality ("new^", "this = whatever") to basic constructors?  Why not use class syntax as an opt-in to these features?

ES classes are only syntax; the objects defined by that syntax are just regular functions. Basically, these functions could have been defined the traditional way and have their properties related to prototypal inheritance manually adjusted afterwards. It would be artificial to limit a feature based on *how* the objects were constructed.

—Claude
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



--
Jeremy Martin
661.312.3853
@jmar777

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: new instantiation design alternatives

Kevin Smith

Sorry to interject, but was the rationale for needing a new syntax for this (vs. an API-based solution) presented anywhere? I can't seem to find it.

Feel free to correct me here...

The current setup (with @@create) was designed to provide sugar for ES5-style OOP.  As such, it separates allocation (the `new` part) from initialization (the constructor part).  It's very elegant.

However, this appears to be unsatisfactory when subclassing built-in and host-provided classes.  For those cases, we don't want to expose "allocated but uninitialized" objects (e.g. DOM objects implemented in C++).  So separating allocation from initialization is not desired for those cases.

This led us to the idea of setting the "this" value from within the constructor itself, essentially fusing "constructor" and "@@create" into one function.

"new^" is argument originally provided to @@create.  (Is that right?)

"this=" is how you initialize the this object (previously the return value from @@create).

Allen, is that a fair run-down?


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: new instantiation design alternatives

Jeff Morrison
In reply to this post by Claude Pache
I'm not sure I understand your point here... Are you saying that the only way to solve the DCE/refactoring problem is to either always implicitly allocate or never implicitly allocate?

-Jeff

On 9/12/14, 7:22 AM, Claude Pache wrote:


Le 12 sept. 2014 à 08:39, Jeff Morrison <[hidden email]> a écrit :

" If a constructor body contains an assignment of the form this = then automatic allocation is not performed and the constructor is expected to perform manual allocation."
If I'm understanding this correctly, this means that snippet (A) would never have access to `this`, but snippet (B) would have an implicit `this` binding -- is that correct?

(A)
```

class Foo extends Bar {
  constructor() {
    if (false) {
      this = super();
    }
    this; // undefined
  }
}
```


(B)
```

class Foo extends Bar {
  constructor() {
    // No call to `this =` present in the constructor
    this; // the automatically allocated object -- i.e. this !== undefined
  }
}
```


If this is the case, it occurs to me that it would raise issues for things like automated refactoring and/or dead code elimination (as a minifier might do).
Normally a minifier (or even a human) would expect to be able to eliminate the entire conditional altogether if they were confident the condition never evaluated to true. But with this static pre-check acting as the indicator for whether automatic allocation/binding should happen, doing so would cause the constructor to act very unexpectedly differently in the two cases.

I wish I could suggest an alternative, but nothing comes to mind right now.

Thoughts?

So, let's explore how to cope with the design that consists to determine the automaticity of allocation/binding independently of the actual code of the constructor (as it was the case in my original design.) 

The rule must be the following one:

* For constructors in classes, automatic allocation occurs if and only if there is no `extends` clause.
* For constructors defined the ES1-5 way (outside classes), automatic allocation occurs.

That is satisfying for most cases while remaining backward compatible with ES1-5, but it is a priori problematic in the following situations, where one may want manual allocation whereas the rule mandates an automatic one.

(1) Base classes (i.e., classes without `extends` clause) that want manual allocation. The legacy possibility of returning an alien object from the constructor remains. Alternatively, the following hack is possible, provided that we accept `Function.prototype` as a constructor.

class Base extends Function.prototype { /* ... */  } 

(IIUC, the prototype chain for both constructor and instances will be the same as without the `extends Function.prototype` clause.) If that situation occurs often, we might want to provide sugar around that.

(2) Constructors defined outside classes that want manual allocation of `this`. For these, I propose the following syntax:

function Derived(a, b) extends Base { /* ... */ }

as an almost equivalent of:

function Derived(a, b) { /* ... */ }
Derived.__proto__ = Base
Derived.prototype = { __proto__: Base.prototype || Object.prototype, constructor: Derived }

except that the automatic allocation of `this` does not occurs in the former case. Like constructors defined in classes, the `extends Function.prototype` trick is possible.

—Claude



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: new instantiation design alternatives

Mark S. Miller-2
Even when written explicitly, either by an IDE or a human, the 

constructor(a, b, c) {
    this = new super(...arguments);
    ...
}

pattern is usually bad. It is fine in a certain special case I mention below. It would be a disaster to have this pattern be the default smoothed over by a syntactic shortcut. Here's the problem:

----- at time v1 -----
class Point {
    constructor(x, y) 
        this.x = x;
        this.y = y;
    }
    equals(otherPt) {
        return this.x === otherPt.x && this.y === otherPt.y;
    }
}

class ColoredPoint extends Point {
    constructor(x, y, color) {
        this = new super(x, y);
        this.color = color;
    }
    // whether we override equals here is not the issue
}

---- at later time/revision v2 ----
class Point {
    constructor(x, y, fudgeFactor = 0.000001) {
        this.x = x;
        this.y = y;
        this.fudgeFactor = fudgeFactor;
    }
    equals(otherPt) {
        return abs(this.x - otherPt.x) <= fudgeFactor &&
                abs(this.y - otherPt.y) <= fudgeFactor;
    }
}
--------

Under normal circumstances, as shown above, this is a valid evolution of the Point class, even without examining or revising existing clients like ColoredPoint. Since the Point constructor had only two non-optional parameters, it could normally assume that existing clients had only called it with two arguments. Thus, it would normally be assumed compatible with existing clients to add new optional arguments. Passing all arguments by default breaks this assumption, making the "fragile base class" problem much worse.

The special case where the super(...arguments) is ok, even needed, is when the base class constructor already has a rest parameter.

EIBTI applies forcefully here.

-- 
  Cheers,
  --MarkM

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
1234 ... 7