Hatena::Groupsicp

SICP読書記

2009-12-14

SICP 3.5 ストリームのところをgaucheでやるときの置き換え

 SICP 3.5 ストリームのところをgaucheでやるときの置き換え - SICP読書記 を含むブックマーク はてなブックマーク -  SICP 3.5 ストリームのところをgaucheでやるときの置き換え - SICP読書記

  • cons-stream -> stream-cons
  • the-empty-stream -> stream-null
  • stream-enumerate-intervalは以下でok
(define (stream-enumerate-interval start end)
  (stream-iota (- end start) start))

など。以下参考に。http://practical-scheme.net/gauche/man/gauche-refj_170.html#SEC479

(追記)SICPを解くに当たっては、以下のstream.scmを使うべき。でも、直感的にはgaucheの実装が気持ちが良い。

http://d.hatena.ne.jp/rucifer_hacker/20090127/1233037207

いずれにしてもここではstreamを理解しさえすればいいので、こまけえことは気にするな!の方向で。

問題 3.50

問題 3.50 - SICP読書記 を含むブックマーク はてなブックマーク - 問題 3.50 - SICP読書記

(use util.stream)

(define (display-stream stream)
  (if (stream-null? stream)      (undefined)      (begin         (display (stream-car stream))        (display "\n")
        (display-stream (stream-cdr stream)))))


(define (stream-map proc . argstreams)
  (if (stream-null? (car argstreams))
          stream-null
          (stream-cons
                (apply proc (map stream-car argstreams))
                (apply stream-map
                           (cons proc (map stream-cdr argstreams))))))

(display-stream
 (stream-map + 
        (stream 1 2 3)
        (stream 40 50 60)
        (stream 700 800 900)))

問題 3.51

問題 3.51 - SICP読書記 を含むブックマーク はてなブックマーク - 問題 3.51 - SICP読書記

(use util.stream)

(define (stream-enumerate-interval start end)
  (stream-iota (- end start) start))

(define (display-line str)
  (begin
    (display str)
    (display "\n")))

(define x (stream-map display-line (stream-enumerate-interval 0 10)))

(define main
  (begin
    (display "(stream-ref x 5)")
    (stream-ref x 5)
    (display "(stream-ref x 7)")
    (stream-ref x 7)))

> gosh p192-3.51.scm

(stream-ref x 5)0

1

2

3

4

5

(stream-ref x 7)6

7

あれ?

1回目のstream-refで5番目までのリストが消費されて、2回目でその次の7番目までが消費されるから

こんな感じになると想像してた

0

1

2

3

4

5

6

7

8

9

10

(ストリーム使い切った)



stream.scm

 stream.scm - SICP読書記 を含むブックマーク はてなブックマーク -  stream.scm - SICP読書記

なんだかgaucheのstreamの実装がSICPの期待と違うっぽい。

以下のstream.scmを使ってやってみたら結果が違った

http://d.hatena.ne.jp/rucifer_hacker/20090127/1233037207

問題3.51

> gosh p192-3.51.scm

0(stream-ref x 5)

1

2

3

4

5(stream-ref x 7)

6

7

問題3.52

(load "./stream.scm")

(define sum 0)
(define (accum x)
  (set! sum (+ x sum))
  sum)

(define seq (stream-map accum (stream-enumerate-interval 1 20)))

(define y (stream-filter even? seq))

(define z (stream-filter (lambda (x) (= (remainder x 5) 0))
  seq))

(display-line "stream-ref y 7")
(stream-ref y 7)

(display-line "display-stream z")
(display-stream z)

これで実行

> gosh p192-3.52.scm

stream-ref y 7

display-stream z

10

15

45

55

105

120

190

210

sumの合計がどこでどうなるって言うのが一つ。

想像するに、(stream-ref y 7)では8回seqが評価されるから、1+2+...+8で40。

displayを入れて実験

> gosh p192-3.52.scm

stream-ref y 7

sum=136

display-stream z

10

15

45

55

105

120

190

210

....。あ、そうか。8つめの偶数が出てくるまで評価されるんだ。

7つめの偶数は2,4,6,8,10,12,14,16で16。1~16の合計は136。

TrishaTrisha2011/04/10 18:192YOG4g Great thinking! That really breaks the mold!

idmooddwagbidmooddwagb2011/04/12 04:42kPLDem <a href="http://jnxznjbewwui.com/">jnxznjbewwui</a>

eizyabbreizyabbr2011/04/13 07:056iMrjp , [url=http://wvvbuylirhkh.com/]wvvbuylirhkh[/url], [link=http://aebieveibhev.com/]aebieveibhev[/link], http://mtrjxksgirct.com/