SICP 4.2.2-4.2.3

4.27

(define count 0)

(define (id x)
  (set! count (+ count 1))
  x)

(define w (id (id 10)))

;;; L-Eval input:
count
;;; L-Eval value:
1

;;; L-Eval input:
w
;;; L-Eval value:
10

;;; L-Eval input:
count
;;; L-Eval value:
2

ちなみに作用的順序の場合は wを定義した時点で (id (id 10))がすべて評価されるので、 count は最初から2になる

4.28

4.29

フィボナッチ数の計算

(square (id 10)) の評価

メモ化なし

;;; L-Eval input:
(square (id 10))
;;; L-Eval value:
100
;;; L-Eval input:
count
;;; L-Eval value:
2

メモ化あり

;;; L-Eval input:
(square (id 10))
;;; L-Eval value:
100
;;; L-Eval input:
count
;;; L-Eval value:
1

4.30

a

問題中の式

(define (for-each proc items)
  (if (null? items)
      'done
      (begin (proc (car items))
             (for-each proc (cdr items)))))

(for-each (lambda (x) (newline) (display x))
          (list 57 321 88))

最初のbeginまで評価すると

(begin ((lambda(x) (newline) (display x)) 57)
       (for-each (lambda(x) (newline) (display x))
                 '(321 88)))

ここで、元々の評価器なら、newlineがevalされ、displayがforceされる。 つまり、 (改行) 57 と印字される。 以下同じ繰り返しなので、正しく動く。 Benの場合もこの場合は同じ。

b

(define (p1 x)
  (set! x (cons x '(2)))
  x)

(define (p2 x)
  (define (p e)
    e
    x)
  (p (set! x (cons x '(2)))))

元々の場合 p1は基本手続きなので遅延無く評価されるため、 (p1 1) は (1 2) を出力する。

p2の p は複合手続きなので引数(set! x (cons x '(2))が遅延され実行されない。

Cyの場合は、両方評価される。 (p2 1) は (1 2) を出力する。

c

すべて基本手続きを使っており、元々遅延していないから

d

好きかどうかと言われても・・・

4.31

lazy や lazy-memo を解釈する処理を追加する。 lazyやlazy-memo月居ていた場合にそれぞれ別のタグをつけておいて、 force-itで解釈して処理を分岐する。

実装する気力が無かったのでカンニング。 いくつか実装方針がある模様。

http://sioramen.sub.jp/blog/2008/02/sicp-422.html

では、 仮引数がpair であればその中をみてタグをつける

wat-aro.hatenablog.com

では、procedure文の形を変えて中に保存している。 コードの変更は後者のが少ないが、実装的には前者のがわかりやすい気がした。

4.32

ググったところ、 car部も遅延されているので未定義の関数を格納したリストを定義できる らしい

4.33

クオートされた式を評価する機構が無いので、これを追加してやれば良い。 クオートをどう解釈するか一瞬悩んだが、quoted?ってのがあるらしい。

;eval に追加
((quoted? exp) (eval-quote exp env))
;前後は略

(define (eval-quote exp env)
  (if (list? (cadr exp))
      (eval (make-quotation-list (cadr exp)) env)
      (cadr exp)))

(define (make-quotaiton-list obj)
   (if (null? obj)
       '()
       (let ((first-list (car obj))
             (rest-list  (cdr obj)))
            (list 'cons
                  (list 'quote first-list)
                  (make-quotation-list rest-list)))))

3.34

何のことか分からなかったのでカンニング

http://wat-aro.hatenablog.com/entry/2016/01/10/204424

が、ちょっとついていけなかった。