Note that there are some explanatory texts on larger screens.

plurals
  1. POLanguage that supports serializing coroutines
    primarykey
    data
    text
    <p>I don't think such support exists in current languages. I think what I want to do could be solved by a "workflow engine". But the problem I have with workflow's is generally they are:</p> <ol> <li>Declarative/verbose and I find a imperative style much more succinct</li> <li>Heavyweight, I'll have a lot of simple though diverse little state machines</li> </ol> <p>I've investigated <a href="https://stackoverflow.com/questions/321827/serializing-anonymous-delegates-in-c">serializing iterators in C#</a> but that doesn't get me exactly where I want to be. I'm current looking at putting together a DSL in <a href="http://boo.codehaus.org/" rel="nofollow noreferrer">Boo</a> but not sure if I'll be able to get coroutine-like behaviour into Boo, and be able to serialize it as well. </p> <h2>Example</h2> <p>Here is limited fictional example of what I'd like to do. The main issue is that at any point in a routine you may need to get user input. The time between inputs could be very long so the state of service will need to be serialized to disk. </p> <pre><code> def RunMachine(user) var lever = user.ChooseLever() lever.Pull() var device = CreateDevice(user) machine.Add(device) machine.Run() def CreateDevice(user) var color = user.ChooseColor() var shape = user.ChooseShape() return Device(color, shape) </code></pre> <h1>Update</h1> <p>I have a working "engine" in CPython. It piggy-backs on the iterator/yield support in python. So code looks like this:</p> <pre><code>def escape(self, you): roll = yield self.game.rollDice(you) if roll &lt; 5: self.caughtAction(you) </code></pre> <p>Where <code>rollDice</code> can be interrupted. with some user action. <strong>CPython</strong> however doesn't serialize iterators. </p> <p>Since the whole state of the game can be defined as a sequence of commands, I serialize the game state up to the point at where a coroutine started then the remaining list of commands. So to save/restore looks like this:</p> <pre><code>def dumpGameState(game): if gameState.partialState: return pickle.dumps({ 'partialState': game.partialState, 'partialInputs': game.partialInputs }) return pickle.dumps(game) def loadGameState(data): state = pickle.loads(data) if state.__class__ is Game: return state r = pickle.loads(state['partialState']) for input in state['partialInputs']: game.execute(**input) return game </code></pre> <h2>Current Investigations</h2> <p>I still find this unsatisfactory. As I end up having to use 'yield' on almost every method. I'd rather not have to specifically decorate a method. Also it quite fails at serialization. </p> <p>Currently I'm investigating going a functional route, as functional languages seem to have better support for metaprogramming/DSL creation. Currently looking at</p> <ul> <li><a href="http://en.wikibooks.org/wiki/F_Sharp_Programming/Computation_Expressions#Defining_Computation_Expressions" rel="nofollow noreferrer">F# Computational Expressions</a></li> <li>Haskell</li> </ul> <p>I'm hopeful that with strong enough metaprogramming facilities I can automate the state storage mechanism. Also, if I go the F# route, I'm pretty sure I can fall back on the <a href="https://stackoverflow.com/questions/321827/serializing-anonymous-delegates-in-c">"technique"/(hack)</a> I used to serialize iterators.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload