sicp 4 2 2小節部分習題

2021-09-23 16:33:37 字數 1696 閱讀 5482

4.27,

;;; l

-eval input:

(define count 0)

;;; l

-eval value:

ok;;; l

-eval input:

(define (id x)

(set

!count (+1

count))

x);;; l

-eval value:

ok;;; l

-eval input:

(define w (id (id 

10)))

;;; l

-eval value:

ok;;; 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 10),因此此時count為1,當要求列印w的時候force執行了第二步(id 10),因此count增加為2。

4.28,當引數也是函式的時候,例如:

(define square (lambda(x) (

*x x)))

(define (test proc a)

(proc a))

(test square 3)

如果對operator不採用actual-value,那麼square將延時求值,在執行(proc a)時無法辨認eval的過程型別。

4.29,俺第乙個想到的就是樹形遞迴的斐波那契數列:

(define (fib n)

(cond ((=0

n) 0)((

=1n) 1)(

else(+

(fib (-n 

1)) (fib (-n 

2))))))

不帶記憶功能和帶記憶功能的force-it之間的效能差距非常明顯。

第二問,有趣的地方在於square過程,注意到(define (square x) (* x x)),x在body出現了兩次,那麼如果是使用不帶記憶功能的force-it, x將被求值兩次,如果x本身帶有***(例如例子裡面的id過程),那麼顯然***也將被呼叫兩次,因此答案不言自明。帶記憶功能的force-it版本中,count將仍然是1,而在不帶記憶功能的版本中count將增長到2。

4.30,第一問,我也談不出所以然為什麼ben的說法是正確的,關注下第二問的兩個過程在不同eval-sequence下的表現,(p1 1)的結果沒有改變都是(1 2),而(p2 1)在原始版本的eval-sequence中結果是1,而在cy修改後的版本中(對中間步驟採用actual-value)結果是(1 2),也就是說在原始版本中的(set! x (cons x '(2)))的***根本沒有實現,而在修改後的版本中實現了。俺覺的這個問題很迷惑,惰性求值與side effect相互作用很奇特,不過我更偏向原始版本,因為我覺的這樣的實現更容易看清**的意圖,也就是說在透明性上更好,例如我分析p2過程就可以認為直接返回引數x;而實現***很容易讓人掉入陷阱,並且很可能引進難以查詢的bug。

文章**莊周夢蝶  ,原文發布時間2008-11-02

sicp 4 2 2小節部分習題

4.27,l eval input define count 0 l eval value ok l eval input define id x set count 1 count x l eval value ok l eval input define w id id 10 l eval va...

sicp 4 3 3小節習題

本節實現了amb求值器,題目都是擴充套件這個求值器,引入一些特殊的過程。我的嘗試解答從4.51開始 習題4.51,要求實現permanent set 這個過程的 在遇到失敗時不撤銷,實現如下 擴充analyze permanent assignment?exp analyze permanent a...

sicp 3 1 1小節習題嘗試解答

這一節主要是介紹區域性狀態變數,介紹了set 和begin的語法,看來ruby使用 號來表示改變變數值不是什麼新鮮主意。習題3.1,不解釋了 習題3.1 define make accumulator init define accumulator num set init init num ini...