On Dec 30, 2012, at 11:47 AM, Herby Vojčík wrote:

> Hello,
> 
> thinking about class / new / super semantics and its problems, I came with an 
> idea. Big change on the first look, but in fact, imho, not so big and making 
> cleaner model.
> 
> 
> 
> tl;dr
> ----
> 
> Constructor function were workaround to specify constructor for a class 
> without `class`. Now, having `class` nothing presribes the class being 
> equivalent to its constructor. It always brought confusion and now with 
> `constructor` empowered, it brings two-space problem. The `class` keyword can 
> return plain objects, which have `[[Construct]]` calling the constructor of 
> the class.
> 
> 
> 
> The rest is in https://gist.github.com/4413009. If you could please read it, 
> it tries to explain and go a little into detail. I feel this is needed to do 
> now, putting constraints away later would be harder, as I write below:
> 
> 
> 
> Conclusion
> ---
> 
> If `class` would decouple the value it produces (the class) from the 
> constructor function, it would create cleaner and more future-friendly model 
> of classes. Coupling class and its constructor function was a necessity in 
> the past, but now they need not to be coupled. Class.prototype.constructor 
> takes all the responsibility for initializing the instance. This change 
> involves little risk (only pieces of code who actually [[Call]] the "class" 
> for manually initializing it; super-constructor call can be replaced by 
> `super` or `Superclass.prototype.constructor.{call,apply}`). The big spec 
> pieces that involve creation of classes and their instances are already very 
> near and the important pieces need just a few changes. The devil is in the 
> details, the spec is still very 'constructor must be a function'-oriented, 
> but this is mainly in textual parts, algorithms are already generic enough. 
> One important reason to ponder `class` not being constructor function is not 
> conserving this tight coupling which in world of ES6+ with `class` can be 
> seen as antipattern; freeing the contraints now is much easier than doing it 
> later, when this unnecessary coupling is repeated in `class` semantic.
> 
> 
> Thanks, Herby

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:

      //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;

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 over that might be a 
reasonable design choice.  But we have a legacy to consider.  Even if we think 
we should discourage direct calls to class objects (I think I'm now in that 
camp) actually making it an error seems like it may be too big of a step away 
from the legacy conventions.

Allen




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

Reply via email to