我认为当前语言中不存在这种支持。我认为我想做的事情可以通过“工作流引擎”来解决。但是我对工作流程的问题通常是:
- 声明式/冗长,我发现命令式风格更简洁
- 重量级,我会有很多简单但多样的小状态机
我已经研究了 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 中的迭代器/产量支持。所以代码看起来像这样:
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# 计算表达式
- 哈斯克尔
我希望通过足够强大的元编程设施,我可以自动化状态存储机制。另外,如果我走 F# 路线,我很确定我可以依靠我用来序列化迭代器的“技术”/(hack) 。