斜體 表示你須要對斜體部分的含義做出細細的斟酌和思考javascript
加粗字 表示這部份內容是被強調的,須要注意html
本文的目的主要在於解答如下問題:前端
想要理解學習SICP和學習編程有什麼樣的關係?也許這樣一個類比是有益理解的——學習SICP之於編程就像學習 學習 自己。讓咱們再具體點,當咱們在討論學習數學、學習物理時,咱們的研究對象是數學和物理,當咱們在討論學習學習的時候,咱們的研究對象不是某一具體的科目,而是 學習 自己。在其餘地方,你也許見過 元知識 這樣的詞語,其含義表示是 關於知識的知識,和上文講的學習 學習 自己實際上是一個意思。java
那麼:python
解答:es6
相比於元知識,通常性知識更加專一於某一個領域,這使得通常性知識具備了某種特殊性(specialized),而元知識的關注點則更加彰顯了其通用性。之因此區分這兩個概念,是由於這有助於咱們解答如下這個問題——是否存在一種高效且適用於任何領域的學習方法? 或者說 是否存在這樣一種知識,可以使咱們更好的學習、研究其餘知識。顯然,這個問題的描述就是學習元知識的好處。編程
舉個例子:框架
科學方法 就是一種元知識,拿物理學和經濟學來講,這兩門都算科學,但它們研究的對象顯然都不同,物理學更加符合咱們對 科學 這個單詞的認知,那麼經濟學爲何也算科學呢?由於它採用科學方法來研究經濟。注意儘管物理學和經濟學的研究對象不同,甚至能夠說大不相同(通常性知識),可是卻均可以用科學方法(元知識)來研究它們。編程語言
在講述了知識和元知識的關係後,讓咱們回到SICP和編程的關係中來。模塊化
學習SICP並不會教會你如何寫出一個博客、論壇程序(通常性知識)。SICP的目的在於教會你,當你掌握了不管是寫一個博客、仍是一個論壇程序的通常性知識後,如何寫出一個 好 的程序。
以上是從更加籠統的角度談述SICP這本書籍目的,接下來會再具體一點。
本書的做者認爲計算機科學和計算機的關係沒有緊密到須要在名字中帶上計算機三個字,比起說是一門科學,則更像一門藝術,並指出其真正的研究目標在於解決 如何形式化解決問題的過程?
爲了理解這個目標,咱們先來看看什麼是 過程 ?
這裏咱們須要先區分兩種知識:
前者告訴你是什麼,後者告訴你 具體怎麼去作,而 過程就是指令性知識。
因此,再通俗的解釋下,做者認爲的計算機科學的目在於解決,(在計算機中)如何以一種精確、規範性的方法來表述指令性知識
在嘗試達到計算機科學的這一目標時,咱們會遇到一些問題,其中最主要和重要的問題就是 當咱們嘗試構建很是巨大的系統時,咱們如何確信這些系統是正確沒有錯誤的 換句話說 爲何咱們能夠構建出很是巨大的系統,且又保證它們的正確性,這是由於存在着 控制大型系統複雜度的技術。
而 控制大型系統複雜度的技術 就是本書要 實際 討論的主題,本書的目的也在於教會讀者掌握這些技術,因此當你疑惑SICP這本書到底再講什麼的時候,回想下這個這本書的討論的主題,就很容易得出相應的答案了。雖然說本書的主要目的在於教授控制複雜度的技術,可是本書一樣教授了爲掌握這些技術須要學習的基礎知識,而這些基礎知識恰巧也是相關領域的核心部分,這也是爲何SICP被推薦做爲編程入門書的緣由(不是第一本學習編程的書,而是第一本入門編程的書)。
相比較電氣學和物理學來講,計算機科學處理的是一種理想化的組件,咱們的想法和實現之間沒有差距,爲了理解這句話,咱們來看一個例子。一個物理學家10秒鐘能夠撕開1張紙(這個不難),請問物理學家如何在5秒中撕開1張紙?答案很簡單,只要物理學家的撕紙速度加倍就好了。那麼,假設要讓物理學家在1秒中撕開10張紙呢?答案依舊很簡單,只要物理學家的速度變爲原來的100倍就行,但咱們都知道現實中是不可能的。不可能的緣由就是咱們理解 對於計算機科學,咱們的想法和實現之間沒有差距 的關鍵。所以,當咱們嘗試構建一個大型系統時,咱們不會受到物理世界的約束,不須要考慮現實世界的偏差、額外影響,惟一限制咱們的是咱們自身大腦的思惟能力。
咱們先來理解 黑盒抽象 的含義:黑盒抽象是一種有關 使用同樣事物而無需瞭解其內部實現 的思想。
若是細細思考下來,不只於計算機科學,咱們生活的世界其實就構建在這種思想之上。咱們坐飛機不須要考慮飛機的實現原理,咱們買車票而沒必要在意是什麼樣的魔力使得咱們能夠經過一張小紙條就坐上一個嗚嗚叫的運輸工具去往詩和遠方。
讓咱們回到計算機科學中來,來嘗試思考下 爲何咱們須要黑盒抽象?
上文剛纔講述了,當咱們在構建大型系統時,咱們受到的惟一限制就是咱們大腦的思惟能力。黑盒抽象可使咱們從那些實現細節中解放出來,從而有更多的精力來關注咱們想要關注的事物——構建大型系統自己。
其次,也有助於在大型系統中更換組件,咱們依賴黑盒的功能來組織系統,而非黑盒的實現細節,對於實現一樣功能的黑盒來講,咱們不會由於其中一個內部實現用for語句,一個用了while語句,就沒法互換這兩個盒子。
對於黑盒抽象來講,思考如下問題是有益的:
讓咱們看看一些黑盒的例子:
讓咱們以一個簡單的有關 如何找出和抽象盒子中共同的部分 的例子來結束黑盒抽象這部份內容
const cube = x => x * x * x;
const square = x => x * x;
// cube和square是兩個盒子,且都是對元素按次數乘以自身思想的特例
// 如今咱們來表述元素按次數乘以自身思想的通用形式,並將cube和square構建其之上
const power = (x, n) => n === 0 ? 1 : x * power(x, n - 1);
const cube = x => power(x, 3);
const square = x => power(x, 2);
複製代碼
這是個簡單的例子,一眼就能夠看出共通的部分,問題在於程序的規模變大時,其共同的部分就沒法一眼看出了,而SICP則講述瞭如何在規模龐大的系統上找出和抽象共通的部分。
咱們來考慮這樣一個問題:對於一個通用加法系統(不只能夠對數字相加,還能對相加字符串,相加多項式),如何在不影響其餘相加功能的基礎上,增長新的相加功能?
其解決方法就是經過約定接口,瞭解過JAVA的人可能知道JAVA裏有接口的存在,然而要注意的是JAVA的接口只是接口約定思想的一種實現,只要符合接口約定的思想,任何語言均可以構建本身的接口機制。
JavaScript在ES6中也提供了接口,任何一個實現了[Symbol.iterator]方法的對象,就能夠做爲let of的對象,詳見點此
何對複雜的現實世界建模並構造大型程序,有兩種方法:
當純粹的設計已經沒法控制系統複雜度時,一門新的語言也許是一個好的選擇(就像Vue和React)。
這裏談的新語言不是寫一個python或者js出來,設計一門新語言的意圖是爲了強調某一個方面,而且這裏談論的新語言並不是想象中的那麼「重」,舉個例子,之前端來講,Vue和React能夠說就是兩門新的語言,它們構建於JS之上,可使用JS的語法,而且強調了某些細節(數據映射成視圖,自動操做DOM結構),忽略了某些細節(手動操做DOM結構,人腦同步各類狀態)。其中Vue也許比React更像一門新的語言(前者多了一些DSL,後者的JSX只是語法糖),但其中的思想是同樣的。
雖然講述編程語言不是SICP的主要目標,可是本書仍是在這方面提供了很多有益的幫助
SICP提供了一種 通用的編程語言模型,即任何一門語言都要關注如下三點:
由於教授如何掌握編程語言不是SICP的主要目標,儘管提供了相應的幫助,但沒有詳細的發展,王垠的博客裏詳細的擴充了這一段內容,見此。