a小題,這是由於scheme對數字、變數的直接規定,前者會被當作數值型別,後者則會被當作符號型別。因此沒必要將這兩個謂詞新增到資料導向分派中了。如果給數值型別或者符號型別加上乙個標誌,在get的過程中,又對已知的型別做判斷,豈不是在浪費空間和時間。
b小題,我們根據書中已有的範例來完成這道題,也即是第123頁最下面到第125頁最上面的內容。
(define
(install-sum-package)
(define
(addend s)
(car s))
(define
(augend s)
(cadr s))
(define
(make-sum x y)
(cons
((=number? x 0) y)
((=number? y 0) x)
((and
(number? x)
(number? y))
(+ x y))
(else
(attach 'add x y))))
(put 'addend 'add addend)
(put 'augend 'add augend)
(put 'make-sum 'add make-sum)
(put 'deriv 'add
(lambda
(exp var)
(make-sum
(deriv
(addend exp) var)
(deriv
(augend exp) var))))
'done)
;value: install-sum-package
(define
(make-sum x y)
((get 'make-sum 'add) x y))
;value: make-sum
(define
(addend sum)
((get 'addend 'add)
(contents sum)))
;value: addend
(define
(augend sum)
((get 'augend 'add)
(contents sum)))
;value: augend
(install-sum-package)
;unbound variable: put
;to continue, call restart with an option number:
; (restart 8) => specify a value to use instead of put.
; (restart 7) => define put to a given value.
; (restart 6) => return to read-eval-print level 6.
; (restart 5) => return to read-eval-print level 5.
; (restart 4) => return to read-eval-print level 4.
; (restart 3) => return to read-eval-print level 3.
; (restart 2) => return to read-eval-print level 2.
; (restart 1) => return to read-eval-print level 1.
;start debugger? (y or n): n
直到寫到了這一步,我才發現put沒有定義並且不會定義。因此這道題,我曾擱置下來直到通過後面的學習寫出了put和get。
(define operation-table (make-table))
(define put (operation-table 『insert-proc!))
(define get (operation-table 『lookup-proc))
其中的put中的insert-proc加上乙個感嘆號,是因為scheme中的規範——對有破壞性的操作加上」!」。而make-table則在書上第186頁及187頁有定義,沒有學過不要緊,這裡就再來用一次傳說中的按願望思維。
b小題中還要求我們寫出關於積式的求導過程,然後也要安裝到**之中。
(define
(install-product-package)
(define
(multiplier p)
(car p))
(define
(multiplicand p)
(cadr p))
(define
(make-product x y)
(cond
((or
(=number? x0)
(=number? y0))
0)((=number? x1) y)
((=number? y1) x)
((and
(number?
x)(number?
y))(* x y))
(else
(attach-tag 『mul x y))))
(put 『multiplier 『mul multiplier)
(put 『multiplicand 『mul multiplicand)
(put 『make-product 『mul make-product)
(put 『deriv 『mul
(lambda
(exp var)
(make-sum
(make-product
(multiplier exp)
(deriv
(multiplicand exp) var))
(make-product
(deriv
(multiplier exp) var)
(multiplicand exp)))))
『done)
(define
(make-product x y)
((get
『make-product 『mul) x y))
(define
(multiplier product)
((get
『multiplier 『mul)
(contents product)))
(define
(multiplicand product)
((get
『multiplicand 『*)
(contents product)))
注意之前的attach-tag在這裡並不適用,因為其要傳入的引數除了乙個操作符之外有兩個操作物件而不再是乙個。
(define
(attach-tag type-tag x y)
(list
type-tag x y))
(define
(type-tag datumn)
(car datumn))
(define
(type-tag datumn)
(cdr datumn))
這真是一道漫長的題目哎,c小題參照前面兩段**寫起來應該很容易的,如果不知道怎麼做乘冪的這個演算法,在練習2.56中我們已經遇到過了。
最後一題呢,題目給出了另一種的get形式,但是已經寫好的包就不必再加以修改了,因為直接改put即可了。而get中所修改的也只是順序罷了。因此put的改法也只是改改順序。
(put 『make-sum 『add make-sum)
(put 『add 『make-sum make-sum)
前面乙個是之前寫好的,後面乙個是這個小題中改過之後的。 程式設計練習2 7 3
program outme.cpp date 2015 7 4 9 05 53 write by lanxiaor gmail.com 編寫乙個c 程式,它使用3個使用者定義的函式 包括 main 並生成下面的輸出 three blind mice three blind mice see how ...
SICP練習 7 練習1 11
這種題目太像是數學題目了,不過拿到程式設計上又有一些的難度。我們先根據題目中的條件,寫出類似於第 25頁最下面的變換規則。我們先列出如下內容 a f n 1 f 2 f 3 f 4 f 5 b f n 2 f 1 f 2 f 3 f 4 c f n 3 f 0 f 1 f 2 f 3 於是繼而得出下...
SICP練習 12 練習1 18
練習1.8 和前兩題一樣,依舊是只能用對數步數。而且這個迭代過程要基於加 加倍和折半運算。這乙個習題要用到前面的函式,因此最好的做法是,每次都將寫好的 儲存起來。load test1.18.scm 這行 可以用來載入 而儲存可以用c x,c w。以下是該題的 這次我們寫成塊結構 define x y...