3

Let's say I have some function as follows:

function *hello(x) { // define generator
 while (x < 7) {
	console.log(`before: ${x}`)
 x += yield x + 1; // generator object will have value x + 1, then next step of generator has value x + x and not x + x + 1
	console.log(`after: ${x}`)
 }
 return x; 
}
var world = hello(3);
console.log( world.next(2) ); 
console.log( world.next(2) ); 
console.log( world.next(2) );
console.log( world.next(2) );
// before: 3
// {value: 4, done: false}
// after: 5
// before: 5
// {value: 6, done: false}
// after: 7
// {value: 7, done: true}
// {value: undefined, done: true}

I can see that the line with the yield returns a generator object with a value of x + 1, but the actual value of x is only increased by x, not x+1, as can be seen by the values in the before and after console logs. Why is it that the value of x, which comes to the right hand side of the yield is added to the current value of x, but the + 1 is not? I know that the value of x is what is being added, because if I change the value passed to the generator object in the next function, the before and after values reflect how much x was incremented by.

function *hello(x) { // define generator
 while (x < 7) {
	console.log(`before: ${x}`)
 x += yield x + 1; // generator object will have value x + 1, then next step of generator has value x + x and not x + x + 1
	console.log(`after: ${x}`)
 }
 return x; 
}
var world = hello(3);
console.log( world.next(1) ); 
console.log( world.next(1) ); 
console.log( world.next(1) );
console.log( world.next(1) );
// before: 3
// {value: 4, done: false}
// after: 4
// before: 4
// {value: 5, done: false}
// after: 5
// before: 5
// {value: 6, done: false}
// after: 6
// before: 6
// {value: 7, done: false}
// after: 7
// {value: 7, done: true}
// {value: undefined, done: true}

Jack Bashford
44.3k11 gold badges56 silver badges84 bronze badges
asked May 26, 2019 at 23:01

1 Answer 1

3

The value of the expression:

x += yield x + 1;

is not x + 1. The value x + 1 is what is yielded to the caller. The value of yield in the generator is whatever was passed in. In this case, it's always 1 because that's what is being passed to it with:

world.next(1)

A generator stops as soon as it hits the yield so in this case

x += yield x + 1;

You can think of it as working like:

yield x + 1; // pass this value to the called
[Pause]
[Next call from world.next(1)]
x = 1 // value passed in from caller
answered May 26, 2019 at 23:10
Sign up to request clarification or add additional context in comments.

4 Comments

So, after the expression x+1 is yielded to the generator object, it's basically as if everything on the right hand side of yield is dropped when code execution is resumed?
Yes, @emijune the right hand side is not part of the value of the expression. You can think of yield as similar to returning the expression to the right. Then waiting for input to pass to the left.
Got it. So, hypothetically if I did want to increment by x + 1, I would modify the statement to yield x += x + 1 rather than ` x += yield x + 1`. That makes sense, thanks!
Yes @emijune, there is also the option of passing x back into the generator from outside: let g = hello(0); world = g.next(world.value) while world.done is false. This will pass x+1 back into the generator.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.