Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Language that supports serializing coroutines

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:

  1. Declarative/verbose and I find a imperative style much more succinct
  2. Heavyweight, I'll have a lot of simple though diverse little state machines

I've investigated serializing iterators in C# but that doesn't get me exactly where I want to be. I'm current looking at putting together a DSL in Boo but not sure if I'll be able to get coroutine-like behaviour into Boo, and be able to serialize it as well.

Example

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.

    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)

Update

I have a working "engine" in CPython. It piggy-backs on the iterator/yield support in python. So code looks like this:

def escape(self, you):        
    roll = yield self.game.rollDice(you)
    if roll < 5:
        self.caughtAction(you)                  

Where rollDice can be interrupted. with some user action. CPython however doesn't serialize iterators.

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:

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

Current Investigations

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.

Currently I'm investigating going a functional route, as functional languages seem to have better support for metaprogramming/DSL creation. Currently looking at

  • F# Computational Expressions
  • Haskell

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 "technique"/(hack) I used to serialize iterators.

like image 413
Joseph Kingry Avatar asked Apr 09 '09 15:04

Joseph Kingry


Video Answer


1 Answers

Funny that you should ask this today, and then later I read about Continuations in Mono. Looks like the kind of thing you're after. In particular there's a reference to Microthreading in Second Life, including this description:

SecondLife required that code be suspended at any point in time and that its entire state be serializable into a format suitable for storage into a database. Serialized state could then be restored at a different point in time or on a different computer (for example while moving from node to node).

Unless I've misunderstood you, this could be a good avenue to explore.

like image 76
Jon Skeet Avatar answered Nov 11 '22 10:11

Jon Skeet