Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delegated yield (yield star, yield *) in generator functions

ECMAScript 6 should be bringing generator functions and iterators. A generator function (which has the function* syntax) returns an iterator. The iterator has a next method which, when repeatedly called, executes the body of the generator function, repeatedly pausing and resuming execution at every yield operator.

The ECMAScript 6 wiki on generators also introduces the "delegated yield" yield* operator as follows:

The yield* operator delegates to another generator. This provides a convenient mechanism for composing generators.

What does "delegate to another generator" mean? How can I use yield* to "conveniently compose generators"?

[You can play with generators in Node v0.11.3 with the --harmony-generators flag.]

like image 815
Randomblue Avatar asked Jul 05 '13 14:07

Randomblue


People also ask

What is yield in generator function?

The yield keyword pauses generator function execution and the value of the expression following the yield keyword is returned to the generator's caller. It can be thought of as a generator-based version of the return keyword. yield can only be called directly from the generator function that contains it.

What is yield delegation?

Delegating to another generator means the current generator stops producing values by itself, instead yielding the values produced by another generator until it exhausts it. It then resumes producing its own values, if any.

What is Yield * in JavaScript?

In JavaScript, yield is used to pause the execution of a function. When the function is invoked again, the execution continues from the last yield statement. A function that yields values is a generator.

What is yield delegation in JavaScript?

The yield* expression is used to delegate to another generator or iterable object.


2 Answers

Delegating to another generator means the current generator stops producing values by itself, instead yielding the values produced by another generator until it exhausts it. It then resumes producing its own values, if any.

For instance, if secondGenerator() produces numbers from 10 to 15, and firstGenerator() produces numbers from 1 to 5 but delegates to secondGenerator() after producing 2, then the values produced by firstGenerator() will be:

1, 2, 10, 11, 12, 13, 14, 15, 3, 4, 5 

function* firstGenerator() {      yield 1;      yield 2;      // Delegate to second generator      yield* secondGenerator();      yield 3;      yield 4;      yield 5;  }    function* secondGenerator() {      yield 10;      yield 11;      yield 12;      yield 13;      yield 14;      yield 15;  }    console.log(Array.from(firstGenerator()));
like image 108
Frédéric Hamidi Avatar answered Sep 30 '22 15:09

Frédéric Hamidi


Delegated yield doesn't have to delegate to another generator only, but to any iterator, so the first answer is a bit inconclusive. Consider this simple example:

function* someGenerator() {     yield 0;     yield [1,2,3];     yield* [1,2,3]; }  for (v of someGenerator()) {     console.log(v); }

There isn't another function inside the generator itself - yet yield* [1, 2, 3] delegates to the Array.prototype[@@iterator] method.

like image 38
Inoperable Avatar answered Sep 30 '22 16:09

Inoperable