Homunculus Reticulli
Homunculus Reticulli

Reputation: 68376

Javascript Generators question - explain this code

I am reading "The JavaScript Handbook" by Flavio Scopes. He introduces the concept of Generators.

function* calculator(input) {
  var doubleThat = 2 * (yield(input / 2))
  var another = yield(doubleThat)
  return (input * doubleThat * another)
}

// He then runs the following code

const calc = calculator(10)
console.log(calc.next())

Output

{value: 5, done: false}

calc.next(7);

Output:

{value: 14, done: false}

I understand the first output, but I don't understand the second one. Why is the output 14?

My understanding is that the next time .next() is called on calc, it should continue on the line AFTER the one on which it last paused.

Well, that line is this one: var another = yield(doubleThat) and the value of the variable doubleThat at that point should be 10, so I'm expecting the second yield to return an object with a value of 10.

I don't think the example in the book is a good one, as I understand the concept of Generators (Python) and Iterators (C++/Python), and I understand other Javascript examples of Generators - but I simply do not understand what is going on here.

Can anyone explain why the value returned after calc.next(7) is 14?

Upvotes: 5

Views: 109

Answers (2)

Ced
Ced

Reputation: 17327

function* calculator(input) {
  var doubleThat = 2 * (yield(input / 2))
  var another = yield(doubleThat)
  return (input * doubleThat * another)
}

const calc = calculator(10)
console.log(calc.next()); 

At that point you reach the first yield that is 10 / 2.

Then

calc.next(7);

the code is now this

var doubleThat = 2 * (7) // yield expression transformed into 7

Therefor the value is 14

You can gain some insight with the debugger

function* calculator(input) {
  var doubleThat = 2 * (yield(input / 2))
  var another = yield(doubleThat)
  return (input * doubleThat * another)
}

const calc = calculator(10)
debugger;
console.log(calc.next()); 
debugger;
console.log(calc.next(7))

The only weird thing is that when you enter the second next the debugger gets you on the second line of the function, seemingly not executing the 2*7. I think that's just seemingly because it doesn't stop mid expression but I could be wrong.

Upvotes: 3

Pointy
Pointy

Reputation: 413702

The call to .next(7) provides a value for that first yield expression, overriding the value 5 that it previously computed and returned. It's a two-way relationship. The first yield "pauses" mid-expression, to be clear. Execution continues from inside that expression, not the next statement.

That said, I am inclined to agree that it's a questionable example, because I'm not sure that's a realistic situation. It's hard to imagine code like that constructed on purpose for some real application.

Upvotes: 4

Related Questions