Gauche > Archives > 2013/07/14

2013/07/14 08:58:28 UTCKei
#
このcall/ccは結構な処理系で無限ループになりますね。とりあえず手元にある処理系でなったのは、Chez、Mosh、Ypsilon、Sagittarius、Chickenが無限ループでした。ChibiとGaucheだけですね、5を返したのは。
2013/07/14 10:23:08 UTCshiro
#
ああ、引数を捕捉した時に既に元の値が取り出されているってケースがありえるのか。なぜ無限ループになるのかわかりました。これは引数の評価順に依存するから元の式の振る舞いは不定ですね。
#
ちなみにGaucheでなぜ常に5が返るかというと、2引数で一方がローカル変数参照の場合、どういう順序でもそうでない方の引数を先に評価するようにコンパイルされるのです。その方がスタック操作が少なくて済むので。
2013/07/14 15:10:26 UTCkaki
#
(let ((x 0) (cc '()))
  (set! x (let ((y (call/cc (lambda (c)
                              (set! cc c)
                              (c 1)))))
            (+ y x)))
  (if (< x 4)
      (cc 2)
      x))
#
引数の評価順に依存しないように書き直すとこうでしょうか.これならGaucheでもRacketでも5になりました.