Hi all, Long-time lurker, first-time poster. Profuse apologies if this was mentioned before and I failed to find it.
I've been using V8's generator implementation in Node 0.11.x recently, and have come across what I believe is a footgun with generators currently. That is - the ability to return a value, not just yield a value. I am proposing that while `return;` is still allowed, `return value;` becomes a syntax error within generators. An alternative proposal is to implicitly treat `return value` within a generator as `yield value; return;`, however this would create a difference in the semantics between `return;` and `return undefined;` that currently doesn't exist and I believe such a thing has been proposed before unsuccessfully in http://esdiscuss.org/topic/void-as-a-value There are a couple reasons I believe this should be a syntax error. Firstly, for-of doesn't support it, thereby making it a bit halfway-there to start with: function * upToThree() { yield 1; yield 2; return 3; } for(var num of upToThree()) { console.log(num); // 1, then 2. Never logs 3 } It also makes it impossible to return an empty iteration (or at least, impossible to distinguish an empty iteration from an iterator that has a single undefined value): function* empty() { return; // or is it // return undefined; ? } Supporting that style also has knock-on effects for consuming generators like takeUntil (which will execute a function on each value, and yield them until it reaches one where the function returns true). Functions like this will have to precompute the _next_ value to see if they should yield or return the current value. For example: function * takeUntilThree(iterator) { var curr, next; next = iterator.next(); while(!next.done) { curr = next; next = iterator.next(); if (next === 3) { // only know which to do based on the _next_ value) return curr.value; } else { yield curr.value; } } return curr && curr.value; // Note: the undefined vs empty problem is still not fixed. } var untilThree = takeUntilThree(upToThree()); untilThree.next(); // { value : 1, done : false } untilThree.next(); // { value : 2, done : true } For these reasons, I find the ability to return a value from a generator is not useful (though I may have missed a use case). Given that any generator with an occurrence of `return value;` can be reimplemented cleanly as yield value; return; I suspect we can remove the footgun by throwing early when an attempt to return a value is encountered within a generator. I must admit I'm not across how difficult this would be for implementers. But I believe it will remove potential danger for developers without harming any real usages. Thanks for listening! Apologies for length! Adam
_______________________________________________ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss