Shiro Kawai
shiro****@lava*****
2005年 8月 11日 (木) 20:18:33 JST
letrecにおけるこの問題は、性能と両立させようとすると難しいんですよね。 ところで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するような気がします。 ;; もっとも、Cのスタックコピーによるファーストクラス継続は ;; あまり安全でもないので、特にアプリ組込みに特化した実装では ;; サポートしない、という選択もありだと思います。 From: Jun Inoue <jun.l****@gmail*****> Subject: [Anthy-dev 2214] r5rs: letrec のバグ(?) Date: Thu, 11 Aug 2005 02:03:19 -0700 > Gauche では意図どおりの動作をします。不思議なことに前方参照も OK で > す。でも (letrec ((a b) (b a)) b) ってやると固まります。 前方参照がOKなのではなくて、最適化によって変数bそのものが消されて いるんだと思います。こんな変換がかかってるはず。 (letrec ((a x) (b a)) b) => (letrec ((a x)) a) 循環参照で固まるのはたぶんコンパイラがこの最適化をかけようとして 無限ループに入ってるからですね。 --shiro