Я не думаю, что такая поддержка существует в текущих языках. Я думаю, что то, что я хочу сделать, можно решить с помощью «механизма рабочего процесса». Но проблема, с которой я сталкиваюсь с рабочим процессом, обычно заключается в следующем:
- Декларативный / многословный, и я считаю императивный стиль более лаконичным
- Тяжеловес, у меня будет много простых, но разнообразных маленьких конечных автоматов
Я исследовал сериализацию итераторов на C #, но это не дает мне точного ответа. хотеть быть. Сейчас я собираюсь собрать DSL в Boo, но не уверен, что смогу поведение, подобное сопрограмме, в 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. Он использует поддержку итератора / yield в 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 #
- Haskell
Я надеюсь, что с достаточно сильными средствами метапрограммирования я смогу автоматизировать механизм хранения состояний. Кроме того, если я пойду по маршруту F #, я почти уверен, что смогу вернуться к методу " "/ (hack) Я использовал для сериализации итераторов.