Jun Inoue
jun.l****@gmail*****
2005年 8月 12日 (金) 06:09:52 JST
On Thu, 11 Aug 2005 01:18:33 -1000 (HST) Shiro Kawai <shiro****@lava*****> wrote: > ところでsigschemeはまだファーストクラスの継続を持っていない > ようですが、もし将来実装するのでしたら、valsのリストを破壊的に > 更新しているところが引っかかるかもしれません。例えばこんな場合: > > (letrec ((a (call/cc (lambda (k) k))) > (b '(1 2))) > (a (lambda (x) x)) > b) => (1 2) > > aが呼び出されると、このforループ中のScmOp_evalに戻ってくる > はずですが: > > for (val = vals; !SCM_NULLP(val); val = SCM_CDR(val)) { > SCM_SETCAR(val, ScmOp_eval(SCM_CAR(val), env)); > } > > この時既にvalsリストは一度評価した値で破壊的に置き換えられているので > bの評価がfailするような気がします。 うを、そんなケースが そうか第一級継続があると ScmOp_eval は複数回返ってくるかも知れないんです ね。 letrec に関しては vals リストを vars リストと一緒に作るんではなく て vals 評価時に作っていくことで解決できそうですけど、他にもいっぱいあり そう。 > ;; もっとも、Cのスタックコピーによるファーストクラス継続は > ;; あまり安全でもないので、特にアプリ組込みに特化した実装では > ;; サポートしない、という選択もありだと思います。 それに継続捕捉が高価ですからね。リソース消費を抑える方法としては、せいぜ い遅延コピーするぐらい? 勝手に longjmp できなくなりますが。 ;; そういえば現在実装されている関数の名前は call/ec にしたほうが ;; よくないですか? >kzk さん > 前方参照がOKなのではなくて、最適化によって変数bそのものが消されて > いるんだと思います。こんな変換がかかってるはず。 > > (letrec ((a x) (b a)) b) => (letrec ((a x)) a) > > 循環参照で固まるのはたぶんコンパイラがこの最適化をかけようとして > 無限ループに入ってるからですね。 なるほど、gauche は最適化するんでしたね。すっかり忘れてました。ありがと うございます。 -- Jun Inoue jun0****@users*****