[Python-ideas] x=(yield from) confusion [was:Yet another alternative name for yield-from]
Guido van Rossum
guido at python.org
Sat Apr 4 22:48:19 CEST 2009
On Fri, Apr 3, 2009 at 6:47 PM, Jacob Holm <jh at improva.dk> wrote:
> 1) We have a coroutine that expects you to call send and/or throw with
> specific values, and ends up returning a value. A beginner may try to
> iterate over it, but will most likely get an exception on the first next()
> call because the input is not valid. Or he would get an infinite loop
> because None is not changing the state of the coroutine. In any case, it is
> unlikely that he will get to see either StopIteration or the new exception,
> because the input is not what the coroutine expects. The new exception
> doesn't help here.
> 2) We have a generator that e.g. pulls values from a file, yielding the
> processed values as it goes along, and returning some form of summary at the
> end. If I iterate over it with a for-loop, I get all the values asn usual
> ... followed by an exception. Why do I have to get an exception there just
> because the generator has some information that its implementer thought I
> might want? Ignoring the value in this case seems perfectly reasonable, so
> having to catch an exception is just noise here.
Sorry, I read this message after writing a long response to an earlier
message of you where I rejected the idea of new syntax for returning a
value from a generator. I find this example somewhat convincing, and
more so because the extra processing of ReturnFromGenerator makes my
proposal a bit messy: there are three "except StopIteration" clauses,
all with parallel "except ReturnFromGenerator" clauses.
Though the real implementation would probably merge all that code into
a single C-level function.
And new syntax *is* a much bigger burden than a new exception. I think
I need to ponder this for a while and think more about how important
it really is to hold the hand of newbies trying to write a vanilla
generator, vs. how important this use case really is (it's easily
solved with a class, for example).
> 3) We have a coroutine that computes something expensive, occationally
> yielding to let other code run. It neither sends or receives values, just
> uses yield for cooperative multitasking. When it is done it returns a
> value. If you loop over this coroutine, you will get a bunch of Nones,
> followed by the new exception. You could argue that the new exception helps
> you here. One way of accessing the returned value would be to catch it and
> look at an attribute. However, for this case I would prefer to just call
> close on the generator to get the value afterwards. A beginner might be
> helped by the unexpected exception, but I think even a beginner would find
> that something strange was going on when the only value he gets for the loop
> variable is None. He might even look up the documentation for the coroutine
> he was calling and see how it was supposed to be used.
Well if you have nothing else to do you could just use "yield from"
over this coroutine and get the return value through that syntax.
And if you're going to call next() on it with other activities in
between, you have to catch StopIteration from that next() call anyway
-- you would have to also catch ReturnFromGenerator to extract the
I don't believe that once the generator has raised StopIteration or
ReturnFromGenerator, the return value should be saved somewhere to be
retrieved with an explicit close() call -- I want to be able to free
all resources once the generator frame is dead.
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-ideas