Nick Coghlan wrote:
Using 'yield return' rather than a bare return wouldn't get any objections from me. As has been said before, the current SyntaxError definitely makes it easier to learn some of the ins and outs of generators.
That would leave us with:
'yield': pass a value back to and receive a value from this generator's client 'yield from': pass control to a subgenerator and receive a value back from it 'yield return': finish this generator with GeneratorReturn 'return': finish this generator with StopIteration
FWIW, I still don't see the need for a GeneratorReturn exception. I don't understand why it should be an error to ignore the return value, or to loop over a generator that returns a value. I assume it makes sense to someone since it is being discussed, so perhaps one of you someones would care to explain it?
I think that leaves us with one remaining question: should we save the return value on the generator iterator and make it available as the return value of the close() method?
I think so, yes. It makes a big difference to some of the examples I have shown.
My inclination is that finalising a generator in a way that allows the return value to be retrieved should be left out of the PEP for now, as it is something that can be: a) easily done externally to the generator*
Yes, you can hack your way around most limitations. In this case if you need the feature it makes quite a big difference to both the calling and the called code.
b) added to close() later if we decide it would be a good idea
That is true, but I think the semantics of "yield-from" becomes more coherent if we do it now. Alternatively, we could drop the "yield return" idea from the proposal and make "yield from" a statement. I would hate to see it go because coupled with returning the value from close it has some really nice uses, but that would be the other way I see to make the proposal coherent. Having "yield return" without returning the value from close just feels wrong.
In order to leave that avenue open in the future however, close() must be defined in the PEP to trap GeneratorReturn as well as StopIteration.
But if we do that without storing the value and returning it on the next close, you cannot use "yield return" as a response to GeneratorExit in a subiterator without losing the returned value. (This of course depends on how we end up handling GeneratorExit and close in the yield-from expression). Instead you will need to manually raise a different exception in the subiterator. And if you do that, the resulting generator can no longer be closed *without* some wrapper to catch the exception.
So +1 to having close() accept GeneratorReturn as a legitimate reaction to being thrown GeneratorExit, but -0 on saving the return value on the generator iterator object (at least in the initial version of the PEP)
And I am +1/+1 on this, although I would rather see the "yield return" statement just storing the value directly on the generator, raising a normal StopIteration, and not using a GeneratorReturn exception at all. - Jacob