5

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?

1
  • I first got really excited about generators playing with p5, that Processing-like "art" library. The need for all sorts of coordinated iteration goes great with generators, because the "iteration" can be nicely hidden in generator functions that can be composed in all sorts of neat-o ways. Commented May 8, 2019 at 12:38

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

2 Comments

The first yield "pauses" mid-expression --Does that mean, when the second next is called, it takes the argument and puts it in place of the paused position?
@KrishnaPrashatt yes exactly. Generators are very powerful but this particular example is strange because it's not clear why one would ever want to do something like that (alter a computation).
3
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.

Comments

Your Answer

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.