Difference between Yield and Yield* operators in Ecmascript 6.0 "Harmony"?

Asked

Viewed 253 times

7

I’m studying the use of generators in Ecmascript 6.0 "Harmony".

I have already managed to understand its basic functioning, like the statement through the syntax function* () { ... } and value production through the operator yield.

However, I still cannot find a satisfactory explanation for the operation of the operator yield*. In the page on generators of the official language wiki the following code, which would be equivalent to that operator, in terms of the operator yield:

let (g = <<expr>>) {
    let received = void 0, send = true, result = void 0;
    try {
        while (true) {
            let next = send ? g.send(received) : g.throw(received);
            try {
                received = yield next;
                send = true;
            } catch (e) {
                received = e;
                send = false;
            }
        }
    } catch (e) {
        if (!isStopIteration(e))
            throw e;
        result = e.value;
    } finally {
        try { g.close(); } catch (ignored) { }
    }
    result
}

Still I could not clearly understand the purpose or effect obtained with the use of this operator. Someone could explain to me?

1 answer

5


I’m still crawling on ES6, but from what I understand yield* is necessary when you want to delegate the yield to another Gen. I found a simple example:

let delegatedIterator = (function* () {
  yield 'Hello!';
  yield 'Bye!';
}());

let delegatingIterator = (function* () {
  yield 'Greetings!';
  yield* delegatedIterator;
  yield 'Ok, bye.';
}());

// Prints "Greetings!", "Hello!", "Bye!", "Ok, bye."
for(let value of delegatingIterator) {
  console.log(value);
}

Notice that yield* delegatedIterator; consumes completely the delegatedIterator. If you used yield delegatedIterator.next(), the exit would be "Greetings!", "Hello!", "Ok, bye.".

Well, that’s how I understood it, but as I said I’m not quite sure on ES6 yet. And I couldn’t find a tool to test this...

  • Oh. I think I finally understand the "delegation" possible with the yield*! Thank you very much :) Just to confirm, in your explanation you meant to say yield delegatedIterator.next(), right? (In case it would produce only one element.)

  • Oops, yes! I’ll fix it. Curiosity: what tool can I test this code on? I tried it on FF and Node 0.8, it gave syntax error.

  • Generators support is being tested on Node 0.11, through flag --harmony, but as far as I know, they still don’t support the operator yield*. Facebook recently released a tool that automatically translates ES6 code with generators to valid ES5 code, called Regenerator. A colleague created a module that transparently calls this translator to run his code on Node, called gnode. It works with 0.8, and supports the yield*. It’s what I’ve been using for my tests.

  • Thanks, @Marcoaurélio! I will try this module, and also update my Node.

  • Just remembering that Node 0.11 is an experimental version (Node follows the impar convention = beta, par = release) You can use the tool n, (https://github.com/visionmedia/n) to keep several versions of Ode installed, and switch between them. (I just don’t know if it works on Windows.)

  • Thanks anyway. Mac usage, and I just upgraded to 0.10.22 (stable) via n. @Marcoaurium

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.