Allen Wirfs-Brock wrote:

On Jan 7, 2013, at 4:09 PM, Herby Vojčík wrote:



Allen Wirfs-Brock wrote:
OK, I ready you proposal. I'll summaries it:

class Sub extends Super {
constructor (...args) {
super(...args); //or super.constructor(...args) because they mean the
same thing.
}
}

creates an (almost) ordinary object that is the initial value of the
Sub binding. The [[Prototype]] of Sub is the value of Super. Sub is
created with a "prototype" property whose value is a new ordinary
object whose [[Prototype]] values is Super.prototype. Sub.prototype
has a method property named "constructor" whose value is a super
bound method function with the user specified body. There is nothing
special about this method, it it just like any other method defined
in a class declaration. In particular it does not have a
[[Construct]] internal property.

The only thing exotic about Sub is that the object has a
[[Construct]] internal method. It does not have a [[Call]] internal
method. The definition of its [[Construct]] in almost JS pseudo code is:


(1):
//internal method this.[[Constructor]](argList):
let newObj = this.@@create(); //eg Sub.@@create();
let replacementObj = this.prototype.constructor.apply(newObj, argList);
if (typeof replacementObj == "object"&& replacementObj !== null)
return replacementObj
return newObj;
(end of (1))

Implications:
Sub === Sub.prototype.constructor evaluates to false.
To create a new instance of Sub say:
new Sub()
The following is a TypeError, because Sub does not have a [[Call]]
internal method:
Sub()
The following is a TypeError, because Sub.prototype.constructor does
not have a [[Construct]] internal method:
new Sub.prototype.constructor()
Sub.prototype.constructor can be called directly or as a method
invocation including via a super call a subclass of Sub.

It seems to me, all you have accomplished here is to make it illegal
to call a class object directly as a function. If we were starting

From technical PoV*, yes.
Oh, and I fixed the super / new inconsistency.

I just don't see such an inconsistency in the current ES6 spec. draft. A
constructor is just a function that is usually called with a this value.
This is true whether it is called by the [[Constructor]] internal method
or via a super/super.constructor call. In either case, the primary
purpose of the constructor is to perform initialization actions upon the
this value. Where is the inconsistency?

(I claim that) in any circumstances, what developers want to express when writing `super(...args)` in the constructoro of SubFoo, is: "On my this, which is now instance of SubFoo, I want the identical initialization code to be run, which `new Foo(...args)` would run to initialize newly created instance of Foo"

That's not true. Because the spec is trying to serve two masters: F and F.prototype.constructor. It is impossible.

The fixed semantics of [[Construct]] for `class` ((1) above) is fixing this by only serving one master: F.prototype.constructor (in line 3).

The only anomaly I see is that a handful of legacy built-ins do
completely different things for new operator originated calls in
contrast to regular function calls. There is no confusion in the spec.
about this and the mechanism for accomplishing it. However such split
behavior can't be declaratively defined in a normal function or class
declaration. In the other thread at
https://mail.mozilla.org/pipermail/es-discuss/2013-January/027864.html I
described how this split behavior an be procedurally described in such
declarations and also described how the same technique can be applied to
the offending built-in constructors (r any user defined class
constructor) to discriminate between initialization and "called"
behavior, even when called via super.
Yes, but it is a workaround.

Bonding identity of class with identity of constructor is not a law. It was just a workaround to make "class" without `class`. Nor, ultimately, can it be said it is preferred by the crowd (they have little other oossibility, it is not a preference but a legacy; similar to "assigment is user preference over Object.define" was not true, because of ES3 legacy and ES5 being fairly new; I think this is the same pattern).

Physical separation allows it naturally, should one want it. By stopping serving F and serving F.prototype.constructor exclusively in new/super.

The only "fix" I saw that you made to super was that in you sketch
constructor methods defined via a class definition are only used for
instance initialization, so there doesn't need to be any code to
determine between initialization and call behavior. Constructor behavior
is always initialization behavior.

Yes, it is there. As a free bonus, btw. The main druver for the design was new/super two masters fixing. Then, later (Brendan Eich will not like this ;-) ) the beauty of breaking the tight coupling and not needing [[Call]] at all for object with [[Construct]].

There are in fact TWO freebies:
 - [[Call]] separated from [[Construct]]
 - you get default constructor for free; by not defining it explicitly.

When such freebies appear, for me this is the signal that someth8ing "clicks", eg., the design matches requirements very good.

However, you don't support non-new invocation behavior, at all, on class
objects so you can't use a class to self-host an implementation of, for
example, RegExp. You also, don't do any thing to support correct

Read the rest of the reply, please. The exact contrary is in fact true. I do. (meta question: why it is so often here that people are cutting the rest and reply only on the first line dismissing the rest?) The proposal was first step: do class as plain objrct with [[Construct]], thereby blessing class/constructor separation. The second step is: when plain object can do, anything can do (the only question is how to specify it).

It was sketched with more examples in the rest.

initialization of subclass of built-ins such as RegExp and Number that
have different behaviors for "called as constructor" and "called as
function".

Allen

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

Reply via email to