構造過程抽象
心智的活動,除了盡力產生各種簡單的認識之外,主要表現在如下三個方面:
- 將若干簡單的認識組合爲一個複合認識,由此產生出各種複雜的認識。
- 將兩個認識放在一起對照,不管它們如何簡單或者複雜,在這樣做時並不將它們合而爲一。由此得到有關它們互相關係的認識。
- 將有關認識與那些在實際中和它們同在的所有其他認識隔離開,這就是抽象,所有具有普遍性的認識都是這樣得到的。
————John Locke, An Essay Concerning Human Understanding
1. 程序設計的基本元素
一種強有力的程序設計語言,不僅是一種指揮計算機執行任務的方式,它還應該成爲一種框架,使我們能夠在其中組織自己有關計算過程的思想。每一種強有力的語言都爲此提供了三種機制:
- 基本表達形式————用於表示語言所關心的最簡單的個體
- 組合的方法—————通過它們可以從較簡單的東西出發構造出複合的元素
- 抽象的方法—————通過它們可以爲複合對象命名,並將它們當作單元去操作
在程序設計中,我們需要處理兩類要素:過程和數據。非形式的說,數據是一種我們希望去操作的“東西”,而過程就是有關操作這些數據的規則的描述。這樣,任何強有力的程序設計語言都必須能表述基本的數據和基本的過程,還需要提供對過程和數據進行組合和抽象的方法。1.1 表達式
1.2 命名和環境
1.3 組合式的求值
處理組合式的求值,按照如下的方式進行處理:
- 數的值就是它們所表達的數值。
- 內部運算符的值就是能完成相應操作的機器指令序列。
- 其他名字的值就是在環境中關聯於這一名字的那個對象。
環境所扮演的角色就是用於確定表達式中各個符號的意義。1.4 複合過程
Lisp 提供的一些基本元素,包括:
- 數和算術運算是基本的數據和過程。
- 組合式的嵌套提供了一種組合起多個操作的方法。
- 定義是一種受限的抽象手段,它爲名字關聯相應的值
過程定義是一種威力更加強大的抽下技術,通過它可以爲複合操作提供名字,而後就可以將這樣的操作作爲一個單元使用了。1.5 過程應用的代換模型
有兩種形式:
- 正則序———完全展開而後歸約。
- 應用序———先求值參數而後應用(Lisp),可以避免重複求值。
編寫程序(課後習題 1.5)來驗證解釋器是哪一種。然後求值下面表達式,即可知道。
- (test 0 (p))
解釋:首先 (define (p) (p)) 定義了一個死循環,直接調用 (p) 進入死循環。
- 如果是正則序,首先替換 (test x y) 中的 x,y,得到 (test 0 (p))。因此替換後得到:(if (= 0 0) 0 (p)),於是跳過了死循環。
- 如果是應用序,首先計算 (test x y) 的每個參數,計算 y ( (p) ) 時,就進去死循環了。
在 guile 的測試中,程序進入了死循環,說明是應用序求值的。
1.6 條件表達式和謂詞
關鍵詞 cond、and、or、not 的使用。1.7 實例:採用牛頓法求平方根
1.8 過程作爲黑箱抽象
對於平方根的計算問題,可以自然的分解爲若干子問題:一個解怎樣算作足夠好?怎樣去改進一個解等等。這些工作中的每一個都通過一個獨立的過程完成,整個 my-sqrt 程序可以看作一族過程,它們直接反應了從原問題到子問題的分解。過程的分解如下圖所示:
內部定義和塊結構。 如下程序中嵌套的定義稱爲
塊結構。如下程序中,在外圍的 my-sqrt1 被調用時,x 由實際參數得到自己的值,這種方式稱爲
詞法作用域。
參考: