Gauche > Archives > 2020/06/22

2020/06/22 09:42:00 UTChamayama
#
現状は、以下のような感じでしょうか。
(1) Racket の call/cc は、R7RS の call/cc と互換性はない。
(例えば「R7RS の記述に解釈の余地があって、Racket の call/cc も認められる」ということはない)
#
(2) Racket の racket/control ライブラリは、R7RS の call/cc をベースにして実装することはできない。
(Racket on Chez では、Chez Scheme の call/cc + 独自機能を使って実装している (#%call-in-continuation, #%$null-continuation, #%$current-attachments あたり?))
2020/06/22 13:41:19 UTCkaki
#
Racketの call/cc ってR7RSの call/cc と互換性ないんですか?R7RSの範囲で、どういうケースで違いが出ますか?
2020/06/22 15:13:59 UTChamayama
#
ああ、prompt-tag を指定しなければ、両者は同じものになるということでしょうか?
2020/06/22 15:17:33 UTCleque
#
1. Racketのcall/ccはshift/resetを使わなければR7RSと互換なはずです
#
2. できないという認識です。continuation markは処理系のサポートが必要ですし(Racket on Chez はcontinuation attachementをchez側に追加しています)、call/ccで限定継続を実装すると、必要のない継続まで捕捉してしまいます
2020/06/22 15:32:07 UTChamayama
#
ありがとうございます。勘違いしていました。
2020/06/22 15:35:59 UTCleque
#
あと、call/ccでshift/resetを実装すると、ホスト側のcall/ccやdynamic-wind等々はそのままでは使えなくなります(Racket CSではcall/cc等もRacket向けに再実装しています)。これはメタレベルの高い言語でいろいろやると対象言語で予期しないことが起きるからです(Cで低レベルな操作をすると、その上で実装された言語側のinvariantが壊れる的な
2020/06/22 15:58:22 UTChamayama
#
うーむ。現状、一番近そうなのが、continuation-mark や継続のカット機能だけ vm.c に追加して、あとは Scheme のプログラムで対応するということでしょうが。。。
#
ちょっと難しすぎて実装のイメージができないですね。
#
ただ、実装はともかくとして、理論的には R7RS の上位互換になっているというのは、よい話ですね。
2020/06/22 16:10:20 UTCleque
#
最近のGaucheの実装をちゃんと理解していないんですが、Racketの挙動に合わるなら、とりあえずは (1)resetのときに、dynamic-windや例外ハンドラのチェーンにもプロンプトを入れておく (2)継続を切り出すときにプロンプトを見て例外ハンドラ等も切り出す。さらに、call/pcで切り出したもの(composable continuation)かcall/ccで切り出したもの(non-composable continuation)か覚えておく (3)継続起動時にcomposable continuationかnon-composable continuationかで処理を切り替える、くらいでいいのでは
#
例外ハンドラや動的束縛を一般化する場合はcontinuation markも入れた方がいいですが、それは次の段階ということで
#
あと、abortの追加も必要か
2020/06/22 17:11:04 UTChamayama
#
これまでの経験だと、元の call/cc を限定継続版に変更した時点で、ふるまいが大きく変わるようでした。
例えば、prompt-tag に対応していないと、reset のネストから guard で脱出したときにリークするようになります。
どうも、Racket の方式は、複数の仕組みが連携して成立していて、中途半端に取り入れると壊れる印象です。
段階的に対応するのであれば、Racket on Chez のように、まずは既存の仕組みの上に積み上げる形で対応していく方がよいように思います。