The result of Generator.prototype.return

# Axel Rauschmayer (10 years ago)

If I understand, correctly, someGeneratorObject.return(v) usually produces { value: v, done: true}. The alternative would be that this method returns immediately (with undefined) and queues up that object to be returned by next(). That’s what would happen if the generator itself executed a return statement.

I don’t know which alternative makes more sense, but I’d love to find out more about the rationale behind this particular design decision.

# Kevin Smith (10 years ago)

All three generator methods do the same basic thing: they resume the generator with a "completion" and return the next-yielded-value (or the return value, if done is true). The only difference is which type of completion is used to resume the generator: "normal", "throw", or "return".

# Axel Rauschmayer (10 years ago)

OK. I see the use case for throw() (e.g. to convert a promise rejection into an exception when using generators for async). The only use case for return() is closing an iterator, then(?)

# Kevin Smith (10 years ago)

Or for closing a data sink, if you're using a generator that way.

In particular, "return" is called on an iterable in the event of an early exit from a for-of loop, in order to allow the iterable to release resources or perform other cleanup.

# Axel Rauschmayer (10 years ago)

Right (also: destructuring, spread, etc.). I was mainly wondering whether there was any other use case for return().

# Bergi (10 years ago)

Axel Rauschmayer schrieb:

OK. I see the use case for throw() (e.g. to convert a promise rejection into an exception when using generators for async). The only use case for return() is closing an iterator, then(?)

If you are using generators for async, then you'd call return() when your result promise is cancelled.

# Dean Landolt (10 years ago)

On Wed, Feb 25, 2015 at 2:39 PM, Bergi <a.d.bergi at web.de> wrote:

If you are using generators for async, then you'd call return() when your result promise is cancelled.

That seems a bit surprising to me -- I'd expect a cancelled promise to result in some kind of exception being thrown into my coroutine-style generator, not for execution to silently return out of the generator entirely. IIUC calling return on a coroutine would be analogous to a TCP-preserving control flow construct. While this could prove useful in the future, it doesn't really line up with anything in the language as is, so for POLA's sake, coro runners should probably stick to next and throw.

That said, perhaps it's worth contemplating other control flow constructs to be invoked at the yield site, like break and continue (with label as the argument)?

# Bergi (10 years ago)

Dean Landolt schrieb:

That seems a bit surprising to me -- I'd expect a cancelled promise to result in some kind of exception being thrown into my coroutine-style generator, not for execution to silently return out of the generator entirely.

Why? That's just what cancellation means. You can't do anything any more anyways, as there is nothing to return a result to (assuming a pure algorithm of course, but would you really like to execute side effects on cancellation?). It is the same as if the coro runner simply dropped your generator and the yield never returned - except finally-blocks would still be executed.

IIUC calling return on a coroutine would be analogous to a TCP-preserving control flow construct

What's TCP-preservation? (Not exactly a googleable term)