花了三周左右時間讀完了 "Structure and Interpretation of Computer Programs" 第一章,完成了大部分的習題春贸,在這里記錄下書中的一些精華段落浊服,以及個人的一些感悟裁奇。
Iteration vs Recursion
首先季蚂,截取一段書中對于“迭代和遞歸”的描述:
The contrast between the two processes can be seen in another way. In the iterative case, the program variables provide a complete description of the state of the process at any point. If we stopped the computation between steps, all we would need to do to resume the computation is to supply the interpreter with the values of the three program variables. Not so with the recursive process. In this case there is some additional “hidden” information, maintained by the interpreter and not contained in the program variables, which indicates “where the process is” in negotiating the chain of deferred operations. The longer the chain, the more information must be maintained.
這段描述再配合上計算 factorial 的過程(process)插龄,把迭代和遞歸的區(qū)別清晰地展示了出來昙楚。
遞歸從“形狀”上看近速,先增大再縮小堪旧;而迭代卻是線性的削葱。這里所謂的“形狀”就是計算所需要的空間。
另外淳梦,遞歸還需要把一部分“隱藏狀態(tài)”交給 interpreter 來維護析砸;而迭代卻是把所有的狀態(tài)放在參數(shù)里。這樣導致的結(jié)果就是爆袍,如果計算過程中斷首繁,迭代可以從中斷的地方開始繼續(xù)執(zhí)行作郭,而遞歸則不行,因為那部分隱藏的狀態(tài)已經(jīng)丟失了蛮瞄。
再截取書中的一段注解#30:
When we discuss the implementation of procedures on register machines in chapter 5, we will see that any iterative process can be realized “in hardware” as a machine that has a fixed set of registers and no auxiliary memory. In contrast, realizing a recursive process requires a machine that uses an auxiliary data structure known as a stack.
當然所坯,遞歸也有優(yōu)點,遞歸能讓我們更好的理解問題挂捅,而且在處理一些有層次關(guān)系的數(shù)據(jù)時芹助,用遞歸更自然。
One should not conclude from this that tree-recursive processes are useless. When we consider processes that operate on hierarchically structured data rather than numbers, we will find that tree recursion is a natural and powerful tool.32 But even in numerical operations, tree-recursive processes can be useful in helping us to understand and design programs.
此外闲先,書中把 Process 和 Procedure 的對比描述地也很精彩状土。簡單來說,Process 屬于概念上的東西伺糠,跟具體語言無關(guān)蒙谓,而 Procedure 是用具體的編程語言把 Process 實現(xiàn)出來。
迭代過程(iterative process)也可以用遞歸程序(recursive procedure)來實現(xiàn)训桶,因為 Scheme 之類的語言實現(xiàn)支持“尾遞歸”(tail-recursive)累驮,因此常見的 for,while 之類的循環(huán)原語只是作為語法糖(syntatic sugar)而存在。而其他沒有支持尾遞歸的語言(C, Python)則需要借助 for,while 來實現(xiàn)迭代過程舵揭。
讀完第一章后谤专,不得不佩服本書的兩位作者,平淡的幾句話就能把很多深刻的問題解釋地非常透徹午绳,可能這也就是為什么這本書在老派的程序員當中相當受推崇置侍。
接下來幾天(也許幾周?)準備寫下第一章的重點:使用程序(procedure)來構(gòu)建抽象拦焚,從而使得復雜的邏輯更簡單易懂蜡坊,也更靈活易改。
P.S. 如果想對遞歸/尾遞歸有更深入的了解赎败,這篇文章絕對值得一看~