そのようなサポートは現在の言語には存在しないと思います。私がやりたいことは「ワークフローエンジン」で解決できると思います。しかし、私がワークフローで抱えている問題は、一般的に次のとおりです。
- 宣言型/冗長性と私は命令型のスタイルがはるかに簡潔だと思います
- ヘビー級、私はたくさんのシンプルで多様な小さなステートマシンを持っています
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#計算式
- Haskell
十分に強力なメタプログラミング機能があれば、状態ストレージメカニズムを自動化できることを期待しています。また、F#ルートを使用すると、イテレータのシリアル化に使用した「テクニック」/(ハック)に頼ることができると確信しています。