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