第一章 構造過程抽象

歡迎關注個人博客網站 waterlaw.topexpress

心智的活動, 除了盡力生產各類簡單的認識以外,主要表如今以下三個方面:函數

1)
將若干簡單的認識組合爲一個複合的認識, 由此產生出各類複雜的認識。網站

2)將兩個認識放在一塊兒對照,無論它們如何簡單或者複雜,在這樣作時並不將它們合而爲一。由此獲得有關它們的相互關係的認識。指針

3)將有關認識與那些在實際中和它們同在的全部其餘認識隔離開,這就是抽象,全部具備廣泛性的認識都是這樣獲得的。code

-- John Locke. (有關人類理解的隨筆, 1690)

Lisp 語言包含了 9 種思想

  1. 條件結構(即"if-then-else"結構)。如今你們都以爲這是理所固然的,可是 Fortran I 就沒有這個結構,它只有基於底層機器指令的 goto 結構。
  2. 函數也是一種數據類型。在 Lisp 語言中,函數與整數或字符串同樣,也屬於數據類型的一種。它有本身的字面表示形式(literal representation),可以儲存在變量中,也能看成參數傳遞。一種數據類型應該有的功能,它都有。
  3. 遞歸。Lisp 是第一種支持遞歸函數的高級語言。
  4. 變量的動態類型。在 Lisp 語言中,全部變量實際上都是指針,所指向的值有類型之分,而變量自己沒有。複製變量就至關於複製指針,而不是複製它們指向的數據。
  5. 垃圾回收機制。
  6. 程序由表達式(expression)組成。Lisp 程序是一些表達式區塊的集合,每一個表達式都返回一個值。這與 Fortran 和大多數後來的語言都大相徑庭,它們的程序由表達式和語句(statement)組成。區分表達式和語句,在 Fortran I 中是很天然的,由於它不支持語句嵌套。因此,若是你須要用數學式子計算一個值,那就只有用表達式返回這個值,沒有其餘語法結構可用,由於不然就沒法處理這個值。
  7. 符號(symbol)類型。符號其實是一種指針,指向儲存在哈希表中的字符串。因此,比較兩個符號是否相等,只要看它們的指針是否同樣就好了,不用逐個字符地比較。
  8. 代碼使用符號和常量組成的樹形表示法。
  9. 不管何時,整個語言都是可用的。Lisp 並不真正區分讀取期、編譯期和運行期。你能夠在讀取期編譯或運行代碼;也能夠在編譯期讀取或運行代碼;還能夠在運行期讀取或者編譯代碼。

應用序與正則序

正則序: 解釋器首先對運算符和各個運算對象求值,然後將獲得的過程應用於實際的參數。舉個粒子:
預先定義:對象

(define (square x)
    (* x x))
(define (sum-of-squares x y)
    (+ (square x) (square y)))
(define (f a)
(sum-of-squares (+ a 1) (+ a 2)))

求表達式 (f, 5) 的值。遞歸

(sum-of-squares (+ 5 1) (+ 5 2))
(+ (square (+ 5 1)) (square (+ 5 2)))
(+ (* (+ 5 1) (+ 5 1)) (* (+ 5 2) (+ 5 2)))
(+ (* 6 6) (* 7 7))
(+ 36 49)
85

這種「徹底展開然後歸約」的求值模型稱爲正則序求值。與之相對的是現代解釋器採用的是先求值參數然後應用的方式,它稱爲應用序求值字符串

條件表達式和謂語

(cond (<e1> <p1>)
(<e2> <p2>)
..
(<en> <pn>))
(if <pred> <conse> <alter>)
(and <e1> <e2> ...<en>)
(or <e1> <e2> ... <en>)
(not <e>)

實例

Ben 發明了一種方法檢測解釋器採用哪一種方式求值,他定義了一個過程:get

(define (p) (p))
(define (test x y)
(if (= 0 x)
    0
    y))

然後他求下面表達式的值:博客

(test 0 (p))

若是解釋器採用應用序求值, Ben 將會看到什麼? 若是解釋器採用正則器求值, Ben 又會看到什麼?假設 if 語句在兩種求值方式中的規則是同樣的, 即謂詞老是先被執行。

答: 若是解釋器採用應用序求值, 那麼必須知道表達式 (p) 的值, (p) 是一個調用本身的函數。

(test 0 (p))
(test 0 (p))
...

反之若是解釋器採用正則序求值,那麼

(test 0 (p))
(if (= 0 0)
0
(p))
0

說明性知識與行動性知識

採用牛頓法求平方根

平方根函數可定義爲: 根號 x = 存在這樣的 y, y >= 0 而且 y^2 = x;

(define (sqrt x)
(the y (and (>= y 0)
(= (sqrt y) x)
))

這樣又從新提出了原來的問題。函數只不過是描述一件事情的特徵,並無描述如何計算的過程。在數學裏,人們一般關心的是說明性的描述(是什麼),而在計算機科學,人們一般更關心行動性的描述(怎麼作)。計算機如何計算平方根呢? 最經常使用的就是牛頓的逐步逼近法。這一方法告訴咱們:若是。。。

相關文章
相關標籤/搜索