yield and new : SpiderMonkey and the draft Spec

Dmitry A. Soshnikov dmitry.soshnikov at gmail.com
Tue Mar 15 12:56:45 PDT 2011


On 15.03.2011 21:13, John J. Barton wrote:
> On 11:59 AM, 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
> g.next.apply(foo,[]);  // true

No, here you set `this` value of the `next` activation, not for the 
context of the continuation. Notice, the state of the CC's (current 
continuation) context is set only once -- at it's creation. The creation 
is done (by the strawman spec) at _first_ call to `next` method. In this 
creation of the CC's context, `this` value is taken from the g-object 
itself (and g-object got it when was created by the call to the g-function).

Currently (in non-standardized version in SpiderMonkey), `next` method 
in every single/next call doesn't change `this` value of the CC's 
context, since as said, uses the same context passing it around.

I don't see currently the case when the `this` value should/could be 
changed in every next entering for yielding (in other case it reminds me 
Python again when you can change `self` in runtime).

So all you've done with `g.next.apply(foo,[]);` is just provided `this` 
value as `foo` for the `next` method. And which is caused an exception 
since `next` method is applied not for a generator object, but for the 
`foo`:

g.next.apply(foo, []); // not true, but TypeError

Side note: Notice though, that current SpiderMonkey 1.8.5 shows the 
following exception message: "TypeError: Generator.prototype.next called 
on incompatible Object". However, `Generator` binding is not defined. So 
it's good either to make `Generator` binding available, or to change the 
error message. Note: it's not `Generator` function used in the previous 
example, it's a built-in generators constructor:

console.log(typeof Generator); // "undefined"

let g = (function () {yield}()).next.call(null); // TypeError: 
Generator.prototype.next called on incompatible global

>>
>> However,
>>
>> let g = foo.bar();
>> g.next(); // true
> Could you please explain the reasoning here? I can't figure it out. To 
> me, g.next() has to mean that in "next", this===g.

Yes, absolutely correct. And it does mean exactly this.

However, I was talking about `this` value of the _CC's context_ (not of 
the `next`s context). Perhaps it can be convenient to have a g-function 
as a method of an object and use `this` as that object during all 
reenters to that continuation.

> I can't see a path to conclude that foo is involved.

Well, I can assume this (especially if a programmer isn't so familiar 
with such a style of creating of these coroutines-generators). However, 
if the programmer is familiar with that, then the information how `foo` 
is involved here is taken from the code of the creation of the `g` -- at 
the moment of g-function activation, i.e. when `this` value is provided 
by the caller.

> It's only role is to hold the property 'bar' which is a function 
> constructing 'g'.
>

As is said, we can't say exactly whether it's the only its purpose, 
repeat, it's likely that `this` value normally can be used inside the 
code of the g-function and refer to the needed object.

The other thing is mutable over the reentering the CC `this` value. E.g. 
when we pass it to `next` and `next` then pass it throw to the CC's 
context. Thus, we can't have different `this` value in every next call 
to CC. But it breaks some existing scheme, e.g. with the same checking 
of the `this` to be exactly the generator object in the `next` method. 
And I'm not sure whether different `this` value is needed in different 
reenters to the CC. Moreover, if to consider such coroutines as threads, 
then I guess `this` value should be the same during the whole code of 
the g-function body.

>>
>> 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.
> Perhaps we need a little user testing to see whose claims hold up.
>

Maybe, I'm not against it and opened to different styles and variants, 
though, as I mentioned, this thing that such a generators way seems to 
you unfamiliar can be just a matter of a habit.

Dmitry.


More information about the es-discuss mailing list