継続マラソン - 継続の実装方法を考える11 - SigScheme

ふと。他の処理系の実装方法が気になって SigScheme-0.7.1 のソースを読んでみる。

  • src/continuation.c に大体の処理がまとまっているようだ
  • 「継続を作る」=> setjmp と「継続を call する」=> longjmp


setjmp/longjmp をそのまま使用しているようなので深い方向への継続が動かないんじゃないかなあ。
実験してみよう。
./configure --enable-continuationで sigscheme-0.7.1 をビルド。

nobita% ./sscm
sscm>  (define cont '())
(define f (lambda ()
            1
            ((lambda ()
               2
               (call/cc (lambda (c) (set! cont c)))
               3))
            4))cont
sscm> (f)
f
sscm> 4
sscm> (cont 1)
Error: in scm_call_continuation: expired continuation


なるほど。

今後の方向性を考える

今回の Scheme インタプリタの実装にあたって

  • setjmp/longjmp + スタックコピー
  • S式(or evalした結果)をたどっての継続構築

の2つの方法をみなさんのアドバイスを受けつついろいろと考えたり実験した。


その結果 setjmp/longjmp 方式を採用しようかと。
理由はいくつかあって

  • シンプルである
  • 継続を提供する部分とそれ以外の部分の独立性が保てそう
  • (今の自分の実装と力では)、S式をたどっての継続構築は、見通しがかなり悪くなりそう


あたり。
自分が処理系をたくさん書いたことがあるのであれば違うんだろうけども、現時点ではこんな感じです。


あとは sigscheme のように、完全な継続実装は多少プライオリティを下げても良いかなとも思っていたり。
異論反論歓迎。