支持序列化协同程序的语言

时间:2009-04-09 15:04:48

标签: serialization programming-languages dsl coroutine

我认为目前的语言不存在这种支持。我认为我想做的事情可以通过“工作流引擎”来解决。但我对工作流程的问题通常是:

  1. 陈述/详细,我发现命令式的风格更简洁
  2. 重量级,我会有很多简单但不同的小型状态机
  3. 我已经调查了serializing iterators in C#,但这并没有让我确切地想要成为我想去的地方。我目前正在考虑在Boo中组装一个DSL,但不确定我是否能够在Boo中获得类似协程的行为,并且能够将其序列化。

    实施例

    这是我想做的有限虚构的例子。主要问题是,在例程中的任何时候,您可能需要获得用户输入。输入之间的时间可能很长,因此需要将服务状态序列化为磁盘。

        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)
    

    更新

    我在CPython中有一个工作“引擎”。它捎带在python中的迭代器/ yield支持上。所以代码看起来像这样:

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

    rollDice可以被中断的地方。用一些用户动作。 CPython 但是不会序列化迭代器。

    由于游戏的整个状态可以定义为一系列命令,因此我将游戏状态序列化到协程开始的位置,然后是剩余的命令列表。所以保存/恢复如下所示:

    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
    

    当前调查

    我仍觉得这令人不满意。因为我最终不得不在几乎所有方法上都使用'yield'。我宁愿不必专门装饰一个方法。它在序列化方面也很失败。

    目前我正在调查功能性路线,因为功能语言似乎更好地支持元编程/ DSL创建。目前正在关注

    我希望有足够强大的元编程功能,我可以自动化状态存储机制。另外,如果我使用F#路由,我很确定我可以回到用于序列化迭代器的"technique"/(hack)

5 个答案:

答案 0 :(得分:8)

有趣的是你今天应该问这个问题,然后我读到Continuations in Mono。看起来像你追求的那种东西。特别是有Microthreading in Second Life的引用,包括此描述:

  

SecondLife要求代码   在任何时间点暂停   它的整个状态是可序列化的   成适合存储的格式   进入数据库。序列化状态   然后可以在不同的地方恢复   时间点或不同的   电脑(例如搬家时)   从节点到节点)。

除非我误解了你,否则这可能是一个很好的探索途径。

答案 1 :(得分:5)

我发现序列化coroutines的最佳支持似乎是通过Pluto库在Lua中。

我triend Mono 2.6,但无法使协同程序正常工作。然后我尝试使用Python / IronPython一段时间,但缺乏序列化支持。

现在有了Lua,我将不得不interface via P/Invoke from .NET to Lua这对于在Linux和Windows上工作都是一个挑战,但最终如果我正在寻找支持游戏的脚本语言,可能最好使用已经普遍选择的东西。

<强>更新

我最终放弃了Lua。我在整合问题上陷入了困境。我回到了Python。我正在使用python yield expressions作为我的协同程序,并解决pickle doesn't support generators的问题。

在我的情况下,程序状态并不总是有活动的协同程序,这意味着有时我可以腌制状态。否则,我存储最后的pickle状态,以及之后的动作的“重放历史记录”。然后恢复状态只是取消最后一个状态,并重放任何动作。

答案 2 :(得分:1)

您可能需要查看Windows Workflow:

http://msdn.microsoft.com/en-us/netframework/aa663328.aspx

它意味着以这样的方式使用,能够在工作流不活动时保持工作流,以及重新启动它的能力。

虽然从技术上讲它不是语言支持,但应该完成工作。

答案 3 :(得分:1)

您在寻找continuations吗?

  

在任何支持闭包的语言中,都可以以连续传递方式编写程序并手动实现call / cc。

call/cccall-with-current-continuation

答案 4 :(得分:0)

最新版本的Java包括Rhino,一个支持可序列化延续的javascript解释器。还有冥王星+ Lua,我正在调查。

我想知道您最终采用的路径,因为可序列化的延续对于http://weaverengine.com项目非常重要。