On Mon, Dec 11, 2017 at 6:44 PM, Yury Selivanov <yselivanov.ml@gmail.com> wrote:
On Mon, Dec 11, 2017 at 6:21 PM, Franklin? Lee <leewangzhong+python@gmail.com> wrote:
What about hanging onto just the value, and creating new StopIteration instances instead of raising the same one again?
Doesn't really matter, as we're still prolonging the lifespan of the returned object.
As I said, I don't see a problem with this. How often does one accidentally hold on to an exhausted generator that they no longer have a need for? How often do those held generators have return values? How often are the generators held past the life of their returned values? And if one holds an exhausted generator on purpose, but doesn't need the returned value, what _is_ needed from it? I suspect it's a rarity of rarities.
To me the current behaviour of generators seems fine. For regular generator users this is a non-problem. For trampolines and async frameworks--so many of them have been implemented and all of them worked around this issue in one way or another.
For regular generator users, there is also little harm, as most simple generators won't return values. (Yes, I know the burden of proof is on the one looking to change the status quo.) I haven't figured out if there's a nice way to compose trampolines and memoization. I don't know if it's possible. Are there async frameworks that implement the concept of a coroutine which is also a thunk? I admit again, my use for it is not common. Even for myself. Maybe someone else has a better use?
I would have attached the returned value to the generator object, but for some reason, generator and coroutine objects can't take attributes. Maybe I should ask for that feature instead.
You can use a WeakKeyDictionary to associate any state with a generator; that should solve your problem. We wouldn't want to add __dict__ to generators to have another way of doing that.
I used a regular dict, which was discarded when the total computation was finished, and extracted the function args to use as the key. However, I had to memoize within the trampoline code, and could not use a separate memoization decorator.