yield and new : SpiderMonkey and the draft Spec

David Herman dherman at mozilla.com
Tue Mar 15 10:39:07 PDT 2011


I agree with Dmitry on these points. In short: the new Generator(...) syntax still requires its argument to be a generator function, so you've just added pointless extra make-work to create one. And as Dmitry points out, you can always implement that constructor yourself in JS.

What I think is more important is to have an API that lets you actually test whether a function (which may have been created somewhere else entirely) is a generator function. That's why I added an API to the spec:

    Function.isGenerator(f)

which returns a boolean indicating whether f is a generator function. See:

    http://wiki.ecmascript.org/doku.php?id=strawman:generators#api

JJB: you could use this to make your implementation of a Generator constructor more robust, e.g.:

    function Generator(fn, self, args) {
        if (!Function.isGenerator(fn))
            throw new TypeError("not a generator function");
        this.generatorFunction = fn.apply(self, args);
    }

    Generator.prototype = { ... }

Dave

On Mar 14, 2011, at 3:28 PM, Dmitry A. Soshnikov wrote:

> Moreover, forgot to mention. Passing the generator function ("g-function" and "g-object" for shortness) as an argument for the `Generator` constructor is not good for dynamically bound `this` value (notice, that in Python's `self` is just a casual variable/argument, which should be passed manually anyway).
> 
> I.e. we should have `this` as `foo` in the following example:
> 
> let foo = {
>  bar: function () {
>    yield (this == foo);
>  }
> };
> 
> let g = new Generator(foo.bar);
> g.next(); // false
> 
> However,
> 
> let g = foo.bar();
> g.next(); // true
> 
> You may of course pass the context object as the second argument (thus, providing explicit `self` as in Python):
> 
> function Generator(fn, self) {
>  return fn.apply(self);
> }
> 
> let g = new Generator(foo.bar, foo);
> g.next(); // true
> 
> But I don't see a big need in such a wrapper. If the rules are specified, there should be no any confusion with using call expression for getting g-object, and then use `next` to executed the continuation.
> 
> Dmitry.
> 
> On 15.03.2011 18:42, Dmitry A. Soshnikov wrote:
>> On 15.03.2011 17:58, John J. Barton wrote:
>>> On 3/14/2011 10:08 PM, Brendan Eich wrote:
>>>> On Mar 14, 2011, at 11:50 PM, John J. Barton wrote:
>>>> 
>>>>> On 11:59 AM, Brendan Eich wrote:
>>>>>> However, there's no way for a generator function to return that instance, because a generator function always implicitly returns a fresh generator iterator when invoked. It could store |this| in the heap, and whatever value |this| receives is saved as part of the shallow continuation capture by the generator.
>>>>>> 
>>>>> The implicit return of a fresh generator iterator makes the example confusing.
>>>> It's just like Python.
>>> 
>>> and Python is perfect?  Even successful features have room for improvement.
>>> 
>> 
>> Pyhton's and JS's implementation is just a one of. But for those who work with such an implementation, there should be no a big confusion. Lua in contrast e.g. uses a special `coroutine.create(generatorFn)` (http://lua-users.org/wiki/CoroutinesTutorial)  -- similarly to your proposal. But you may do it yourself if it's confusing
>> 
>> function Generator(fn) {
>>  return fn();
>> }
>> 
>> let g = new Generator(function() {
>>  yield 1;
>>  yield 2;
>> });
>> 
>> g.next(); 1
>> g.next(); 2
>> 
>> From JS/Python's viewpoint, this may be considered as superficial thing -- if you know that the function is a generator function, be prepared that the _call_ creates the generator object. The other call to the same generator function, creates a fresh g-object. And so on. There is no confusion as it would be that the first call create the g-object, and the other calls already yield, no. For yielding `next` method is.
>> 
>> P.S.:
>> 
>> A small change, e.g. can be to make next as a getter since it doesn't accept arguments.
>> 
>> g.next; // 1
>> g.next; // 2
>> 
>> But, it's a cosmetic and actually not so needed change.
>> 
>> Dmitry.
>> 
>>> jjb
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>> 
> 
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss



More information about the es-discuss mailing list