この前のやつ. lconsはcdrのみを遅延させるのに対して、util.streamで定義されてる stream-consは、carもcdrも遅延させる.そうすると、なんか上手く いくようになるみたい.
Gauche ユーザリファレンス: 11.58 util.stream - ストリームライブラリ
gosh> (use util.stream)
#<undef>
gosh> (define fib (stream-cons 0 (stream-cons 1 (stream-map + (stream-cdr fib) fib))))
fib
gosh> (stream->list (stream-take fib 10)) (0 1 1 2 3 5 8 13 21 34)
On Lisp は、殊、継続についてはSchemeのコードも載せててくれる。 やっぱりSchemeはいいなって思う。 非決定性計算については Scheme による choose, fail 関数も載ってた。 マクロじゃないんだね。 せっかくだからそのコードを書き写した。
本に載ってるコードをそのまま載せちゃうのって問題ないのかな。 著作権がどうとか。引用ということに出来ればいいだろうけど。
/scheme/choose-fail.scm.txt
に対して、自分が書いたのが
/scheme/amb.scm.txt
failの定義の仕方が違う。自分は、自分が書いたヤツでいいと思うんだけど。
思うことに、ただひとつの大域変数 paths に、複数のchooseが突っ込んでる けど、これって大丈夫なのかなあ。On Lisp なんかのは、よくある実装と 違って、後ろに追加して前から取り出す。いわゆるキューにしていて、 だから幅優先探索になるんだろうな。きっと。
gosh> (choose 1 2 3)
1
gosh> *paths*
(#<closure (choose #f #f #f)> #<closure (choose #f #f #f)>)
gosh> () ; 2つ残ってる
()
gosh> (choose 0)
2
当然、次のchooseをしても前のが残るよね
これって実用したい時に問題じゃん?
;; 奇数がほしいよお
gosh> (let1 a (choose 2 4 6 9 11) (if (odd? a) a (fail)))
9
;; 今度は偶数がほしいよお
gosh> (let1 a (choose 2 4 6 9 11) (if (even? a) a (fail)))
11
;; ふぁっ?!