GeneratorFunctionPrototype should probably be a function

Allen Wirfs-Brock allen at wirfs-brock.com
Wed Aug 14 10:20:16 PDT 2013


On Aug 14, 2013, at 3:51 AM, Andy Wingo wrote:

> Hi,
> 
> Thanks Allen and André for replying; I admit that I haven't payed much
> attention to the new classy parts of ES6.
> 
> On Tue 13 Aug 2013 19:44, Allen Wirfs-Brock <allen at wirfs-brock.com> writes:
> 
>> instanceof is essentially broken when applied to most non-built-in
>> prototype objects because they usually just aren't defined to proper
>> operate as instances of the associated constructor.
> 
> Why is there a "constructor" link, then, from GeneratorObjectPrototype
> to GeneratorFunctionPrototype, if the latter isn't a constructor?  Or is
> it, somehow?

(I'm going to use the names  from the figure in 15.19.3 and suggest that you reference that diagram while reading the following and remember that in UML the names of associations (properties) are at the opposite end of an association line)

So, why? It's because (Generator) (aka (GeneratorFunction).prototype and (Generator).prototype.constructor) serves two distinct roles.  It is the prototype object associated with the constructor named (GeneratorFunction) and it is an abstract super constructor (ie abstract superclass object).  In the latter role it has an associated prototype object (Generator).prototype, aka (GeneratorFunction).prototype.prototype.  

This arrangement allows the following to work:

function * g(){};
let gObj = new g(); //or just g()
console.log(g instanceof (GeneratorFunction));  //true
console.log(g instanceof Function);  //true
console.log(g instanceof Object); //true
console.log(gObj instanceof g);  //true
console.log(gObj instanceof (Generator)); //true
console.log(gObj instanceof Object); //true
console.log(gObj instanceof Function);  //false

The existence of a 'constructor' property on (Generator).prototype is a direct reflection of the class pattern and {Generator)'s role as an abstract class. In general, a 'constructor' property on a class's prototype (even when abstract) is needed so that a subclass constructor can make a super call to the super class constructor.  However, this scenario isn't applicable to generator functions and generator objects, but we've still followed that general pattern.

There is one intentional anomaly in the application of the class pattern to generator objects. The prototype associated with an individual generator function does not have a 'constructor' own property that references back to the generator function. For example, using the definitions in the above example, the following expression evaluates to false:
   gObj.constructor === g // false because g.prototype does not have a 'constructor' own property

The reason for that was that we didn't want access to a generator instance to implicitly provide the capability to access the associated generator function and hence the capability to create additional generator instances.

If we also did not have a 'constructor' property on (Generator).prototype then gObj.constructor would evaluate to Object. It seems more reasonable for it to evaluate to (Generator) and that is what the existence of (Generator).prototype.constructor enables.  
      


> 
> BTW, I find that the lack of clear names in the spec makes thinking and
> communication difficult.  If you can, I would call them
> "GeneratorFunction", "GeneratorFunctionPrototype", and
> "GeneratorObjectPrototype", in LTR order in the section 15.19.3 diagram.
> They don't have to be bound on the global object, but having well-known
> names in the spec makes it easier to talk about them.

The naming in the spec is the naming that was developed and agreed to at the Nov. 27, 2012 TC-39 meeting https://dl.dropboxusercontent.com/u/3531958/tc39/generator-diagram-1.jpg 

The main rationale for these names goes something like:

Normally a constructor for instances of an abstraction is given the name of the abstraction and we don't formally append "Object" to such names.  Instead we use the abstract name as an adjective to "object" or "instance".  So, "generator objects" are instances of the "generator" abstraction and hence the name of the (abstract) constructor/class should be Generator.  So what do you call the abstraction over the special kind of functions that are the subclasses of Generator?  We decided on GeneratorFunction.  Individual generator functions such as g above are GeneratorFunction instances, just like regular constructor functions are instances of Function.  

Allen
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130814/1c1aca7b/attachment.html>


More information about the es-discuss mailing list