Gauche > Archives > 2020/06/15

2020/06/15 06:53:53 UTCkaki
#
互換性問題としては自分は困らないので何も言えない、未定義挙動みたいなものに依存している方が悪いと言ってしまうのは簡単ですが…理想の話をするなら、限定継続を入れるときに call/cc の意味を整理すべき(だった)と思います。継続に関するオペレータを複数入れておいて、同時に使うと壊れるよというのはScheme的ではないと思いますし。現状ではGaucheの reset/shift は安心して使えないと感じるので、いずれ直すべきだと思います。
2020/06/15 07:00:00 UTCshiro
#
方針として、call/ccは「プログラム全体がresetで囲まれた限定継続」ってことで統合するつもりです。resetなしでshift起動するとshift抜けたところでプログラムが終了するのはそのせい。
#
そのモデルで動いてないとしたら実装のバグなので、互換性の問題とかではなく修正すべきです。ただ、動的環境がどう切り取られるかを真面目に考えないとならないんだけど落ち着いてまとまった時間がとれなくて放置になっちゃってます。
2020/06/15 08:47:05 UTChamayama
#
うーむ、現状、call/cc のキャプチャする継続は、限定継続にはなっていないと思います。
キャプチャ時に vm->cont と vm->handlers と vm->resetChain を保存して、継続の起動時(ジャンプ時)には、その状態に戻しているだけです。
ただ、部分継続の終端に到達した場合については、直近の reset を抜けるような動作になっているので、そこは部分継続に近いと言えます。
ただ、ジャンプ時に、たまった reset を pop してすべて解消してからジャンプするような動きをするので、そこも限定継続とは相性が悪くなっています。
#
あと、安心して使えないという話ですが、
例えば、大規模なアプリの内部で reset を使っていて、全体を guard で囲ってエラー時のリトライをするようにした場合に、
解放されない reset のメモリがあると、長期的にはメモリ不足になる可能性があります。
現状の Gauche では、完全に入れ子になっている状態であれば、guard と reset/shift は干渉しないので、そういう意味では安心という見方もできます。
2020/06/15 09:25:29 UTChamayama
#
このあたり、すべてを限定継続にしてしまって本当に大丈夫なのだろうかと、当時、気になった点ではあります。
2020/06/15 10:14:32 UTCshiro
#
もちろん、call/ccで捕まえる継続は起点から全てのフレームを持ってないとならないですが、ひとつなぎのフレームチェーンをつなぐのではなく「その時点でアクティブな限定継続」のスタックみたいなものを持っておいてそれを捕まえる、という手もあるかなと。実験してみないとわからないですが。アクティベーションレコードをAとして、今はcall/ccもshiftも[A]を捕まえるけれど、call/ccは[[A]]を捕まえることにする。