
On Jun 30, 2013, at 15:08, Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
Ron Adam wrote:
It's the same as in-lineing the generator parts into the iterator that is driving it. We don't need to do that because we already have an optimised version of that. It just needs to catch the StopIteration to be the same. I think that it's not uncommon for people to think this is how list comps work. And I think it is surprising for them that the StopIteration isn't caught.
I tend to feel that the fact that raising StopIteration in a generator has the same effect as returning from the generator is a quirk of the implementation that shouldn't be relied on. I'm not sure we should be giving it official status by going out of our way to make listcomps behave the same.
What other effect could it possibly have? The genexp doesn't do anything special with a StopIteration--it passes it through like any other exception. And this is the same as for an explicit generator function. The calling code--whether it's calling next(), using a for loop, or iterating in C--sees StopIteration for a generator return by definition, and sees StopIteration if explicitly raised because that's how exceptions and generators work. Unless you add an extra new rule that says raising StopIteration inside a generator is illegal and will raise a TypeError or something, there's no other way a valid implementation of Python could possibly work. I think a lot of people are looking at this wrong. In list(genexp), it's not the genexp part that's doing anything here; it's the list function. There's no way that it could distinguish between an explicit StopIteration and an implicit one, so it treats them the same way. If a comprehension is supposed to be the same as list(genexp) it should act like list--or like any other iteration mechanism you can write in Python or even in C--rather than acting magically as it currently does.