計算機程序的構造和解釋(Structure and Interpretation of Computer Programs)

本科畢設的時候林老師推薦過這本書,但是當時看目錄就不知所云。這本書是18年9月剛讀研究生的時候買的,只是一直沒看,連塑封都沒拆開。今年因爲疫情的原因沒上學,大概從3月份開始,花了3個多月的時間仔細讀了一遍,不得不說這書是一片新天地,尤其是當你寫了很多年的命令式。

第一章是構造過程抽象,印象最深的就是用一種通用的過程來實現對一組聚合元素的操作,應該是模板和泛型的概念。另外如果覺得這括號太蛋疼,一定是因爲沒有看視頻教程。

第二章是構造數據抽象,感覺和麪向對象是一個概念,通過實現有理數類和複數類,將Lisp中的所有數運算進行了統一。之前看書沒有注意到的一點是,Lisp中的cons可以綁定到函數上,視頻鏈接見這裏的64:17。

(define cons(a b)
	(lamba (pick)
		(cond ((= pick 1) a)
			   (= pick 2) b))))
(define (car x) (x 1))
(define (cdr x) (x 2))

用C++11中的lambda表達式和function模板來模擬,應該就是下面的代碼,但這裏有兩個問題:

  • 由於函數的返回值只能有一個類型,所以ab必須同類型,不能是兩個類型,可能這就是C++不支持的閉包吧?
  • Cons構造的過程,到底是否和lambda的代換模型一樣?也就是語句是否真的被替換爲了return 37return 49
#include <iostream>
#include <functional>

using namespace std;

template<typename T> function<T(int)> Cons(const T & a, const T &b)
{
	return [a, b](int pick)->T
	{
		if (pick == 1) return a;
		else if (pick == 2) return b;
		else return T();
	};
}

template<typename T> T car(const function<T(int)> &c)
{
	return c(1);
}

template<typename T> T cdr(const function<T(int)> &c)
{
	return c(2);
}

int main()
{
	auto c = Cons<int>(37, 49);
	cout << "Contents of Address part of Register:" << car(c) << endl;
	cout << "Contents of the Decrement  part of Register:" << cdr(c) << endl;
	return 0;
}

這也就是說函數式編程中,數據和過程的界限非常模糊。

第三章是還是數據抽象,但是此時的數據帶有內部狀態,因此要用環境模型代替代換模型。硬件電路模擬約束傳播系統這兩個例子很有意思。最後一部分的流是爲了解決前面出現的串行化問題而提出的一種新的計算模式,我只看懂了有限流部分,無窮流和延遲操作部分沒太理解。

  • 對於硬件電路,每一個元器件的輸入連線中保存了一些過程,這些過程就是設定輸出信號的值,當輸入信號改變時,會將這些過程加入到時間序列中,等待基本門電路的延時之後調用這些過程,所以一個輸入信號就可以層層傳遞到輸出。如果寫過Verilog和VHDL就深有體會了,特別是那個propagate,倍感親切!
  • 對於約束傳播系統,主要用來根據恆等式中一些已知變量的值,來計算另一些變量的值,加減乘除等運算被實現爲約束,變量被實現爲連接線,當連接線被賦新值時,要通知其連接到的另一個約束,而這個約束會對除通知者之外的所有連接線都重新計算賦值

第四章是元語言抽象,實際就是使用Lisp分別實現了Lisp解釋器惰性求值解釋器非確定求值解釋器邏輯式語言解釋器

  • 惰性求值解釋器就是正則序求值解釋器,書中用的Lisp是應用序,也就是在求值一個過程時,所有參數都需要求值纔可以,而惰性求值就只有在參數實際使用時才進行求值
  • 非確定性求值解釋器的名字有點唬人,反正覺得類似於深度搜索,在有多個解時,每執行一次就可以得到一個解
  • 邏輯式語言解釋器的直觀理解就是SQL語言,代碼量比較大,每個過程都好理解,集成後的完整程序沒仔細分析

第五章就沒什麼新鮮的了,首先定義了新的機器語言,最後將Lisp程序和Lisp解釋器編譯爲該機器語言運行,還不如去看編譯相關內容。不過這裏面還是有幾個值得研究的內容,一個是垃圾收集,另一個就是編譯和解釋互相調用的混合策略,同時利用了編譯的效率優勢和解釋的排錯優勢,有點類似於前幾天在知乎上看的一個回答,用python訓練,模型沒問題了再用C++重寫一遍。

現在的大學教育一半隻能接觸到命令式編程,因爲這和個人計算機最接近,但其實像C++、Java和JavaScript中都引入了函數式編程的概念,這些特性讓編程變得更高效了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章