SICP——構(gòu)造程序抽象(二)

1.實(shí)例:采用牛頓法平方根

計(jì)算機(jī)的過程和常規(guī)的數(shù)學(xué)函數(shù)很相似,但它們之間有個(gè)重要差異:過程必須是有效可行的

我們可以把求平方根問題描述為:√ ̄x = y, y>=0而且y2=x ,但是它并沒有描述一個(gè)計(jì)算過程

函數(shù)與過程之間的矛盾,是描述一件事情的特征與描述如何去做這件事之間的普遍性差異的一個(gè)具體反映,即說明性知識(shí)行動(dòng)性知識(shí)之間的差異

計(jì)算思路:牛頓法(逐步逼近方法)

  • 提供一個(gè)猜測(cè)值y
  • 通過執(zhí)行一個(gè)"操作"得到更好的y(求出y和x/y的平均值)
  • 重復(fù),直至猜測(cè)值足夠好

寫成過程:

# 迭代
(define (sqrt-iter guess x)
    (if (good? guess x) 
        guess
        (sqrt-iter(improve guess x) x)))

# 那個(gè)"操作"
(define (improve guess x)
    (average guess (/ x guess)))

# 求平均值
(define (averege x y)
    (/ (+ x y) 2))

# 有多"足夠"(y的平方與x的差值)
(define (good? guess x)
     (< (abs (- (square guess) x)) 0.001))

# 定義一個(gè)"入口"
(define (sqrt x)
    sqrt-iter 1.0 x))  # why1.0?: Scheme區(qū)分整型和十進(jìn)制數(shù)值,例如6除以10得5/3,6.0除以10.0得1.6666666…

sqrt-iter展示了如何不用特殊的迭代結(jié)構(gòu)來實(shí)現(xiàn)迭代,僅使用常規(guī)的過程調(diào)用能力

在謂詞名字的最后用問號(hào)不過是一種風(fēng)格上的約定,對(duì)于解釋器而言,問號(hào)只是普通字符

2.過程作為黑箱抽象

在平方根的計(jì)算問題中,每個(gè)過程都通過一個(gè)獨(dú)立的過程完成,整個(gè)sqrt程序可看作一族過程,反應(yīng)了從原問題到子問題的分解,分解中的每一個(gè)過程完成了一件可以清楚標(biāo)明的工作,這使它們可以用作定義其他過程的模塊(可理解為黑箱),即所謂的過程抽象,一個(gè)過程定義應(yīng)該能隱藏起一些細(xì)節(jié)

過程的定義不應(yīng)該依賴于其作者為形式參數(shù)所選用的名字,參數(shù)是它們所在的過程體中局部的東西

形式參數(shù)的具體名字稱為約束變量,因此可以說一個(gè)過程的定義約束了它的所有形參(聲明了約束變量),這些約束變量以這個(gè)過程的體作為它們的作用域;過程的形式參數(shù)是相應(yīng)過程體里的局部名字

作用域:一個(gè)名字的定義被約束于的那一集表達(dá)式

如果一個(gè)變量不是被約束的,我們稱它為自由的,例如上面的good?的定義中,guess和x是約束變量,abs、square是自由的

在一個(gè)過程里添加內(nèi)部定義,使其局部于這一過程,這種嵌套的定義稱為塊結(jié)構(gòu),它是最簡(jiǎn)單的名字包裝問題的一種正確解決方式,我們還可以把約束變量作為內(nèi)部定義中的自由變量,這種方式稱為詞法作用域

塊結(jié)構(gòu)可以幫助我們將大型程序分解成一些容易把控的片段,塊結(jié)構(gòu)的思想來自程序設(shè)計(jì)語言Algol60

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容