実装Note - 継続の除去

Schemeには call-with-current-continuation (call/cc) という関数があり, 呼び出した時点の継続を取り出すことができます。Common Lispにはありません。

Three Dogmas of Scheme が説得力がありますが, フルの継続というのは, 考え方として不味いと思います。

実用上も, 外側から順番にサブルーチンに降りてきたり順に外側に戻るだけでなく, 突然全然関係ない場所にジャンプできる, というのは, プログラミングを非常に難しくします。longjmp(), siglongjmp() のような。

minilang本体だけでなく, ライブラリもアプリケーションもすべてがこのことを考慮しなければならない, というのが大変なのです。

minilangには, call/ccのような形で継続を取り出す方法はありません。

スタックトレースの深い方向へ (見た目的にはループの外側から内側へ) ジャンプすることはできません。また, 現在の処理を pending にして別の処理をおこなう, ということもできません。

retry / redo

Rubyには, 例外が発生したときに, その例外発生地点からやりなおす retry というメソッドがあります。

minilangではコンパイル時エラーです。

ついでに, 継続とは関係ないですが, redo も使い途がないように思うので, 廃止です。

外部イテレータ

継続がないと, 内部イテレータで外部イテレータを作れません。

Rubyはさまざまな場所でeach (内部イテレータ) が使われているため簡単ではありませんが, minilang コアライブラリについては, まず先に外部イテレータを定義して, それを利用して内部イテレータを作るようにしてみました。