Forwarding `return()` in generators

Bergi a.d.bergi at
Tue Mar 24 23:26:05 UTC 2015

Axel Rauschmayer schrieb:
> Right, it doesn’t look like one needs to know the returned value when forwarding `return()`.

Yeah, to support the iterator protocol as yield* does it one would need 
to forward that value. That might be another good use case for a meta 
property. However, I haven't really grasped what the value is used for, 
so I guess passing `undefined` is just fine.

> But: you need to guard against other ways of reaching `finally`.

Why? I intended to always reach finally, and always close the iterator. 
Also, simplicity ftw :-)

 > That’s not what all the other constructs in ES6 do: they only call 
`return()` if iteration stops abruptly.

Only because all the other constructs in ES6 try to exhaust the 
iterator. And when it's finished anyway, one doesn't need to close it.
There is in fact no problem with calling `.return()` too often, it just 
doesn't do anything to completed generators.

Btw, your `take` function is the perfect example where a non-exhausted 
iterator *should* be closed as return prematurely - like a `break` in a 
for-of loop would.

> Also missing from this code: checking whether the iterator actually has the methods `return()` and `throw()` and responding accordingly.

Yupp, that might need to be added as well. However, the current 
behaviour (without the `forwardReturn = false`) is not that bad: If 
`throw` doesn't exist, it tries the `return` from the finally case 
before throwing a type error.
To implement it correctly, I guess it should be

     try {
         while (--n > 0) {
             var {done, value} =;
             if (done) return item.value;
             yield item.value;
     } catch (e) {
         if (typeof iterator.throw == "function") {
             done = true;
         } else
             throw e;
     } finally {
         if (!done)


More information about the es-discuss mailing list