<div dir="ltr"><div>The state of a generator is not much more that a single Python stack frame plus an integer indicating where in the bytecode the resume point is. But copying/pickling a stack frame is complicated -- it's not just all the locals but also the try/except stack and the expression evaluation stack. Have a look here: <a href="https://github.com/python/cpython/blob/master/Include/frameobject.h">https://github.com/python/cpython/blob/master/Include/frameobject.h</a>. I'm not sure that I want to sign up for making all that stuff copyable (pickling will be an even harder challenge). But perhaps you (and/or another fearless hacker) are interested in trying?</div><div><br></div><div>Or were you just trying to see if the core dev team has spare cycles to implement this for you?</div><div><br></div><div>--Guido<br></div></div><br><div class="gmail_quote"><div dir="ltr">On Tue, Jun 19, 2018 at 3:56 PM Micheál Keane <<a href="mailto:ffaristocrat@gmail.com">ffaristocrat@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><br></div><div>Add a function to generator objects to copy the entire state of it:</div><div><br></div><div>Proposed example code:</div><div><br></div><div>game1 = complicated_game_type_thing()</div><div><br></div><div># Progress the game to the first decision point</div><div>choices = game1.send(None)</div><div><br></div><div># Choose something</div><div>response = get_a_response(choices)</div><div><br></div><div># Copy the game generator</div><div>game2 = game1.copy()</div><div><br></div><div># send the same response to each game</div><div>x = game1.send(response)</div><div>y = game2.send(response)</div><div><br></div><div># verify the new set of choices is the same</div><div>assert x == y</div><div><br></div><div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial"><br></div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial">History:</div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial"><br></div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial">I found this <a href="https://stackoverflow.com/questions/7180212/why-cant-generators-be-pickled" target="_blank">stackoverflow Q&A</a> which among other things linked to <a href="http://peadrop.com/blog/2009/12/29/why-you-cannot-pickle-generators/" target="_blank">an in-depth explanation of why generators could not be pickled</a> and this <a href="https://bugs.python.org/issue1092962" target="_blank">enhancement request for 2.6</a> on the bugtracker. All the reasons given there are perfectly valid.... but they were also given nearly 10 years ago. It may be time to revisit the issue.</div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial"><br></div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial">I couldn't turn up any previous threads here related to this so I'm throwing it out for discussion.</div><div style="font-size:small;text-decoration-style:initial;text-decoration-color:initial"><br></div></div><div><br></div><div>Use case:</div><div><br></div><div>My work involves Monte Carlo Tree Searches of games, eventually in combination with tensorflow. MCTS involves repeatedly copying the state of a simulation to explore the potential outcomes of various choices in depth.</div><div><br></div><div>If you're doing a game like Chess or Go, a game state is dead simple to summarize - you have a list of board positions with which pieces they have and whose turn it is.</div><div><br></div><div>If you're doing<span style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"> complex games that don't have an easily summarized state at any given moment, you start running into problems. </span>Think something along the lines of Magic the Gathering with complex turn sequences between players and effect resolutions being done in certain orders that are dependent on choices made by players, etc.</div><div><br></div><div>Generators are an ideal way to run these types of simulations but the inability to copy the state of a generator makes it impossible to do this in MCTS.<br></div><div><br></div><div>As Python is being increasingly used for data science, this use case will be increasingly common. Being able to copy generators will save a lot of work.</div><div><br></div><div><span style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">Keep in mind, I don't necessarily propose that generators should be fully picklable; there are obviously a number of concerns and problems there. Just being able to duplicate the generator's state within the interpreter would be enough for my use case.</span><br class="m_-8490287762081643857gmail-Apple-interchange-newline"><br></div><div><br></div><div>Workarounds:</div><div><br></div><div>The obvious choice is to refactor the simulation as an iterator that stores each state as something that's easily copied/pickled. It's probably possible but it'll require a lot of thought and code for each type of simulation. </div><div><br></div><div>There's a Python2 package from 2009 called <a href="https://pypi.org/project/generator_tools/" target="_blank">generator_tools</a> that purports to do this. I haven't tried it yet to see if it still works in 2.x and it appears beyond my skill level to port to 3.x.</div><div><br></div><div>PyPy & Stackless Python apparently support this within certain limits?</div><div><br></div><div><br></div><div>Thoughts?</div><div><br></div><br clear="all"><div><div class="m_-8490287762081643857gmail_signature" data-smartmail="gmail_signature">Washington, DC  USA<br><a href="mailto:ffaristocrat@gmail.com" target="_blank">ffaristocrat@gmail.com</a></div></div>
</div>
_______________________________________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" rel="noreferrer" target="_blank">http://python.org/psf/codeofconduct/</a><br>
</blockquote></div><br clear="all"><br>-- <br><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">--Guido van Rossum (<a href="http://python.org/~guido">python.org/~guido</a>)</div>