instantiating generators

Allen Wirfs-Brock allen at wirfs-brock.com
Fri Mar 15 11:08:54 PDT 2013


We discussed the factoring of the generator "object model" at the Nov 27 meeting. In the notes  https://github.com/rwldrn/tc39-notes/blob/master/es6/2012-11/nov-27.md there is a sketch of the hierarchy we agreed to: https://dl.dropbox.com/u/3531958/tc39/generator-diagram-1.jpg 

The design Andy referenced is one I presented at the meeting. It is very close to but not identical to the that sketched in the above linked whiteboard diagram. 

But most JS developers won't need to think about this at all.  They just defined generator constructors using generator expressions or function* declarations and then either implicitly (generator expressions) or explicitly call them to get generator instance.  However, there are edge cases and consistency issues where the actual object model becomes visible and  is need to explain the most reasonable behavior.  For example consider:

function *Interval(start, end) {
   for (;start<=end;start++)  yield start;
}

let i1 = Interval(1,10);
let i2 = Interval(20,10);

It seems most consistent with JavaScript conventions that:
  console.log(i1 instanceof Interval);  //true
  console.log(i1.constructor === i2.constructor);  //true
  console.log(i2.constructor === Interval);  //true
  console.log(Object.getPrototypeOf(i2) === i2.constructor.prototype);

Also i1 and i2 essentially share common implementations of the next,send,throw,close methods that are derived from the body of the Interval generator definition. It makes sense for all instances of Interval to share those methods rather than replicating them as own methods.  This suggests that they belong in a common prototype object.

At the Nov meeting we discussed all these things (and others) and there was fairly strong consensus that this sort of design was needed for provide a plausible meta foundation for explaining and understanding how generators fit with the rest of ES.  That basically matched my personal experience.  I originally created various forms (I think I showed 4 alternatives at the meeting) of that "class hierarchy" diagram to understand what function *(){} was actually doing so I could spec. it adequately. Once I had the full abstraction worked out in this manner. everything became quite clear.  

I acknowledge that SpiderMonkey has had generators without worrying about such details.  To me that simply reflects the difference between the expectations for an initial feature-functionality focused implementation and what we need to do as part of a standard.  Spider Monkey could get away with a more ad hoc design that didn't worry too much about edge cases but as part of a standard that is going to have multiple implementations and needs to support future language evolution it is important that we work through these details and to try to "get it right".

Regarding new Interval(1,10).  People don't need to say that (although I don't think there is anything wrong with thinking about it that way) and if we want to we can make it illegal.  However, I think it is extra design/spec/implementation work to disallow it and it seems like an arbitrary restriction. 

My intent for the near future is to take the consensus whiteboard design from the Nov. 27 meeting and use it as the basis for what goes into the next ES6 draft.

Allen



On Mar 12, 2013, at 10:42 AM, Brendan Eich wrote:

> This is not what we prototyped and shipped in SpiderMonkey starting in 2006, and Rhino and probably other engines cloned, for years. That's not to say we should or shouldn't do it, but I'm always leery of made-up stuff without any prototype-implementation mileage.
> 
> Allen, is there any reason to make things more nested, with hidden (Generator) constructor? I see what you're getting at but the lack of it has never been an issue for JS1.7+ users. When in doubt, flat is better than nested (Zen of Python).
> 
> /be
> 
> Andy Wingo wrote:
>> Hi,
>> 
>> Given "function* g() { yield 1; }", are these equivalent?
>> 
>>   new g();
>>   g();
>> 
>> Somehow I had assumed that /calling/ would be the normal way to
>> instantiate a generator, but I see "new" in
>> http://wiki.ecmascript.org/doku.php?id=meetings:proposed_generator_class_hierarcy_nov_2013.png.
>> 
>> Thanks,
>> 
>> Andy
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130315/15ae46f2/attachment.html>


More information about the es-discuss mailing list