程序的構造和解釋
心智活動
將若干簡單的認識組合為一個複雜的認識,由此產生出複雜的認識
將兩個認識放在一起做對照,不管他們如何簡單或者複雜。這樣做並不將他們合二為一,由此得到的有關他們相互關係的認知。
將有關認識與那些實際中和他們同在的所有其他的認識隔離開,這就是抽象。所有具有普遍性的認識都是這樣得到的
程序設計的基本元素
語言提供的將簡單的認識組合起來成為更複雜認識 三種機制:
基本表達形式: 組成語言的最小單位,個體
組合的方法: 通過他們可以將簡單的組合成為複雜的
抽象的方法:通過他們將複雜對象命名,並將他們作為單元去使用
程序中需要處理 過程和數據兩種元素,數據是一種我們需要去處理的東西,過程就是我們操作數據的規則的描述。 任何語言都需要 能夠表述基本的數據和基本的的過程,還需要提供對過程和數據進行抽象組合的方法。
scheme
表達式
(操作符 參數1 參數2)
解釋器總是按照 從終端讀入一個表達式,對這個表達式求值,而後列印出得到的結果,稱為讀入—求值—列印 的循環, REPL
命名
(define radius 10)
創建名字–對象的關聯。 鼓勵人們採用遞增的方式去開發和調試程序。其中需要注意 的是,其中隱含著 環境的概念,其中保持著 名字—值的關聯
環境在確定表達式中各個符號的意義是十分重要的,如果沒有相關環境的任何信息,那麼說表達式(+ x 1) 是沒有任何意義的。因為需要環境提供x的意義。環境是具有普遍性的概念。他為求值過程提供了一種上下文。對我們理解程序的執行起著重要的作用。
特殊形式
(define x 3) 並不是一個組合式,一般性的求值規則的這種例外稱為 特殊形式。各種不同類型的表達式(有著不同的求值規則) 組成了程序設計語言的語法形式。
組合式的求值
數的值就是他們所表示的數值
內部運算符 的值就是能完成相應操作的機器指令序列, fun
其他名字的值就是在環境中關聯與這一名字的那個對象, 變數
可以將第二種情況看做最後一種情況的特殊情況,像 +, - 等,相應的指令序列就是與之關聯的值
求值該組合式的各個子表達式
將作為最左表達式的值的那個過程應用與相應的實際參數。所謂實際參數就是各個子表達式的求值結果
為了實現對一個組合式的求值過程, 我們必須先對組合式里的每個元素執行同樣的求值過程。 因此,在性質上,這一求值過程是遞歸的。
反覆的執行第一步驟,最終會到達求值中的一個點,在這裡遇到的不是組合式而是基本表達式。例如內部運算符或者其他名字
過程
參數
約束變數、自由變數: 在過程體中扮演者一種非常特殊的角色,形式參數的具體名字是什麼,完全沒有關係,這樣的名字稱為。 一個過程的定義約束了他所有的形式參數,如果一個變數不是被約束的,我們就稱他為自由的。一個名字的定義被約束於的那一個表達式稱為這個名字的作用域, 所以在過程的定義中,被聲明的為形式參數的那些約束變數,就以這個過程的體作為他們的作用域。
過程與他們所產生的計算
線性的迭代和遞歸
第一個為遞歸計算過程, 代換模型展開的形狀是一個先逐步展開而後收縮的形狀。收縮階段為這些運算的實際執行。這種類似性的計算過程由一個推遲執行的運算鏈條刻畫
第二個為線性遞歸計算過程,解釋器只需要維護函數調用的參數,就可完成函數調用。
過程的計算過程和形式:
過程形式: 過程的書寫形式
計算過程: 過程的計算過程
迭代計算過程: 在計算過程中的任何一點,程序的變數都提供了一個有關計算狀態的完整描述。在任何時刻計算停下來,都可以提供參數來重新計算
遞歸過程: 論述的是一個語法形式上的。說明這個過程的定義中,調用了自己
遞歸計算過程: 函數的計算過程的進展方式。而不是過程上的語法形式上的書寫,他們隱含著一些信息,由解釋器維持,來指明所推遲的運算形成的鏈條中的位置。這一計算處在何處,這個鏈條越長,所需要保存的信息也就越多。
為什麼需要區分 計算過程和形式過程? 大部分語言的實踐設計中,對任何遞歸過程的解釋,所消耗的存儲量總與過程調用的數目成正比,即便他所描述的計算過程是迭代的。作為這是一事實的後果就是-----特殊的循環結構: for, while等。scheme 能夠將形式上的遞歸而計算過程為遞歸形式,依然能夠在常數空間上運行,這種實現為: 尾遞歸
fact-iter 遞歸過程講產生迭代的計算過程, 因為展開的計算過程上確實是迭代的,其中的狀態由三個變數保持。解釋器沒有額外的隱含的狀態保存。
斐波那契數列遞歸形式的展開形式
TAG:NASA迷 |