偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

如何掌握程序語言

開發(fā) 后端
作為一個(gè)程序語言的研究者,我深深的知道這種心理產(chǎn)生的根源。程序語言里面其實(shí)有著非常簡(jiǎn)單,永恒不變的原理??吹搅怂鼈?,就可以一勞永逸的掌握所有的程序語言,而不是只見樹木不見森林。

學(xué)習(xí)程序語言是每個(gè)程序員的必經(jīng)之路??墒沁@個(gè)世界上有太多的程序語言,每一種都號(hào)稱具有最新的“特性”。所以程序員的苦惱就在于總是需要學(xué)習(xí)各種稀奇古怪的語言,而且必須緊跟“潮流”,否則就怕被時(shí)代所淘汰。

作為一個(gè)程序語言的研究者,我深深的知道這種心理產(chǎn)生的根源。程序語言里面其實(shí)有著非常簡(jiǎn)單,永恒不變的原理??吹搅怂鼈?,就可以一勞永逸的掌握所有的程序語言,而不是只見樹木不見森林。我想寫一本書,試圖用最簡(jiǎn)單的方式來解釋程序語言(以至于計(jì)算機(jī)科學(xué))的根本性原理,從而讓人可以在非常短的時(shí)間內(nèi)掌握所有程序語言的精髓。但是在還沒有完成之前,我想先提出一些建議和參考書。

對(duì)程序語言的各種誤解

學(xué)習(xí)程序語言的人,經(jīng)常會(huì)出現(xiàn)以下幾種心理,以至于他們會(huì)覺得有學(xué)不完的東西,或者走上錯(cuò)誤的道路。以下我把這些心理簡(jiǎn)要分析一下,希望可以消除一些疑惑。

1.  追求“新語言”。

基本的哲學(xué)告訴我們,新出現(xiàn)的事物并不一定是“新事物”,它們有可能是歷史的倒退。事實(shí)證明,新出現(xiàn)的語言,很多還不如早就存在的。正視這個(gè)事實(shí)吧,現(xiàn)代語言的多少“新概念”不存在于最古老的一些語言里呢?程序語言就像商品,每一家其實(shí)都是在打廣告。而絕大多數(shù)的設(shè)計(jì),包括某些最“艱深”最“理論”的語言里面的概念,都可能是膚淺而短命的。如果你看不透這些東西的設(shè)計(jì),就會(huì)被它們蒙蔽住。過度的熱情和過多的宣傳,往往意味著膚淺。很多語言設(shè)計(jì)者其實(shí)并不真的懂得程序語言設(shè)計(jì)的原理,所以常常在設(shè)計(jì)中重復(fù)的犯前人犯過的錯(cuò)誤。但是為了推銷自己的語言和系統(tǒng),他們必須夸夸其談,進(jìn)行宗教式的宣傳。

2.  “存在即是合理”。

記得某名人說過:“不能帶來新的思維方式的語言,是沒有必要存在的。”他說的是相當(dāng)正確的。世界上有這么多的語言,有哪些帶來了新的思維方式呢?其實(shí)少之又少。絕大部分的語言給世界帶來的不過是混亂。有人可能反駁說:“你怎么能說 A 語言沒必要存在?我要用的那個(gè)庫 L,別的語言不支持,只能用 A。”但是注意,他說的是存在的“必要性”。

如果你把存在的“事實(shí)”作為存在的“必要性”,那就邏輯錯(cuò)亂了。就像如果二戰(zhàn)時(shí)我們沒能打敗希特勒,現(xiàn)在都做了他的奴隸,然后你就說:“希特勒應(yīng)該存在,因?yàn)樗B(yǎng)活了我們。”顯然這個(gè)邏輯有問題,因?yàn)槿绻麣v史走了另外一條路(即希特勒不存在),我們會(huì)過上自由幸福的生活,所以希特勒不應(yīng)該存在。對(duì)比一個(gè)東西存在與不存在的兩種可能的后果,然后做出判斷,這才是正確的邏輯。按照這樣的推理,如果設(shè)計(jì)糟糕的 A 語言不存在,那么設(shè)計(jì)更好的 B 語言很有可能就會(huì)得到更多的支持,從而實(shí)現(xiàn)甚至超越 L 庫的功能。

3.  追求“新特性”。

程序語言的設(shè)計(jì)者總是喜歡“發(fā)明”新的名詞,喜歡炒作。普通程序員往往看不到,大部分這些“新概念”其實(shí)徒有高深而時(shí)髦的外表,卻沒有實(shí)質(zhì)的內(nèi)涵。常常是剛學(xué)會(huì)一個(gè)語言 A,又來了另一個(gè)語言 B,說它有一個(gè)叫 XYZ 的新特性。于是你又開始學(xué)習(xí) B,如此繼續(xù)。在內(nèi)行人看來,這些所謂的“新特性”,絕大部分都是新瓶裝老酒。很多人寫論文喜歡起這樣的標(biāo)題:《XYZ:A Novel Method for ...》。這造成了概念的爆炸,卻沒有實(shí)質(zhì)的進(jìn)步??梢哉f這是計(jì)算機(jī)科學(xué)最致命的缺點(diǎn)。

4.  追求“小竅門”。

很多編程書喜歡賣弄一些小竅門,讓程序顯得“短小”。比如它們會(huì)跟你講 "(i++) - (++i)" 應(yīng)該得到什么結(jié)果;或者追究運(yùn)算符的優(yōu)先級(jí),說這樣可以少打括號(hào);要不就是告訴你“if 后面如果只有一行代碼就可以不加花括號(hào)”,等等。殊不知這些小竅門,其實(shí)大部分都是程序語言設(shè)計(jì)的敗筆或者歷史遺留問題。它們帶來的不是清晰的思路,而是是邏輯的混亂和認(rèn)知的負(fù)擔(dān)。比如 C 語言的 ++ 運(yùn)算符,它的出現(xiàn)是因?yàn)?C 語言設(shè)計(jì)者們當(dāng)初用的計(jì)算機(jī)內(nèi)存小的可憐,而 "i++" 顯然比 "i=i+1" 少 2 個(gè)字符,所以他們覺得可以節(jié)省一些空間。現(xiàn)在我們?cè)僖膊蝗蹦屈c(diǎn)內(nèi)存,可是 ++ 運(yùn)算符帶來的混亂和迷惑,卻流傳了下來?,F(xiàn)在最新的一些語言,也喜歡耍這種語法上的小把戲。如果你追求這些小竅門,往往就抓不住精髓。

5.  針對(duì)“專門領(lǐng)域”。

很多語言沒有新的東西,為了占據(jù)一方土地,就號(hào)稱自己適合某種特定的任務(wù),比如文本處理,數(shù)據(jù)庫查詢,Web編程,游戲設(shè)計(jì),并行計(jì)算,或者別的什么專門的領(lǐng)域。但是我們真的需要不同的語言來干這些事情嗎?其實(shí)絕大部分這些事情都能用同一種通用語言來解決,或者在已有語言的基礎(chǔ)上做很小的改動(dòng)。只不過由于各種政治和商業(yè)原因,不同的語言被設(shè)計(jì)用來占領(lǐng)市場(chǎng)。就學(xué)習(xí)而言,它們其實(shí)是無關(guān)緊要的,而它們帶來的“多語言協(xié)作”問題,其實(shí)差不多掩蓋了它們帶來的好處。其實(shí)從一些設(shè)計(jì)良好的通用語言,你可以學(xué)會(huì)所有這些“專用語言”的精髓。后面我會(huì)推薦一兩個(gè)這樣的語言。

我必須指出,以上這些心理不但對(duì)自己是有害的,而且對(duì)整個(gè)業(yè)界有很大的危害。受到這些思想教導(dǎo)的人進(jìn)入了公司,就會(huì)開始把他們?cè)?jīng)懼怕的這些東西變成教條,用來篩選新人,從而導(dǎo)致惡性循環(huán)。

如何掌握所有的程序語言

可以老實(shí)的說,對(duì)幾乎所有風(fēng)格的程序語言,我都有專家級(jí)的見解。它們?cè)谖业念^腦里如此簡(jiǎn)單,以至于我不再是任何語言(包括函數(shù)式語言)的“支持者”。但是我花費(fèi)了太多的時(shí)間去摸索這條道路,我希望能夠提取出一些“竅門”,可以幫助人們?cè)诙虝r(shí)間內(nèi)達(dá)到這種通用的理解。具體的細(xì)節(jié)足夠?qū)懗梢槐緯?,我現(xiàn)在只在這里提出一些初步的建議。

1. 專注于“精華”和“原理”。

就像所有的科學(xué)一樣,程序語言最精華的原理其實(shí)只有很少數(shù)幾個(gè),它們卻可以被用來構(gòu)造出許許多多紛繁復(fù)雜的概念。但是人們往往忽視了簡(jiǎn)單原理的重要性,匆匆看過之后就去追求最新的,復(fù)雜的概念。他們卻沒有注意到,絕大部分最新的概念其實(shí)都可以用最簡(jiǎn)單的那些概念組合而成。而對(duì)基本概念的一知半解,導(dǎo)致了他們看不清那些復(fù)雜概念的實(shí)質(zhì)。比如這些概念里面很重要的一個(gè)就是遞歸。國(guó)內(nèi)很多學(xué)生對(duì)遞歸的理解只停留于漢諾塔這樣的程序,而對(duì)遞歸的效率也有很大的誤解,認(rèn)為遞歸沒有循環(huán)來得高效。而其實(shí)遞歸比循環(huán)表達(dá)能力強(qiáng)很多,而且效率幾乎一樣。有些程序比如解釋器,不用遞歸的話基本沒法完成。

2. 實(shí)現(xiàn)一個(gè)程序語言。

學(xué)習(xí)使用一個(gè)工具的最好的方式就是制造它,所以學(xué)習(xí)程序語言的最好方式就是實(shí)現(xiàn)一個(gè)程序語言。這并不需要一個(gè)完整的編譯器,而只需要寫一些簡(jiǎn)單的解釋器,實(shí)現(xiàn)最基本的功能。之后你就會(huì)發(fā)現(xiàn),所有語言的新特性你都大概知道可以如何實(shí)現(xiàn),而不只停留在使用者的水平。實(shí)現(xiàn)程序語言最迅速的方式就是使用一種像 Scheme 這樣代碼可以被作為數(shù)據(jù)的語言。它能讓你很快的寫出新的語言的解釋器。我的 GitHub 里面有一些我寫的解釋器的例子(比如這個(gè)短小的代碼實(shí)現(xiàn)了 Haskell 的 lazy 語義),有興趣的話可以參考一下。

幾種常見風(fēng)格的語言

下面我簡(jiǎn)要的說一下幾種常見風(fēng)格的語言以及它們的問題。注意這里的分類不是嚴(yán)格的學(xué)術(shù)性質(zhì)的分類,有些在概念上可能有所重疊。

1. 面向?qū)ο笳Z言

事實(shí)說明,“面向?qū)ο?rdquo;這整個(gè)概念基本是錯(cuò)誤的。它的風(fēng)靡是因?yàn)楫?dāng)初的“軟件危機(jī)”(天知道是不是真的存在這危機(jī))。設(shè)計(jì)的初衷是讓“界面”和“實(shí)現(xiàn)”分離,從而使得下層實(shí)現(xiàn)的改動(dòng)不影響上層的功能。可是大部分面向?qū)ο笳Z言的設(shè)計(jì)都遵循一個(gè)根本錯(cuò)誤的原則:“所有的東西都是對(duì)象(Everything is an object)。”以至于所有的函數(shù)都必須放在所謂的“對(duì)象”里面,從而不能直接被作為參數(shù)或者變量傳遞。這導(dǎo)致很多時(shí)候需要使用繁瑣的設(shè)計(jì)模式(design patterns) 來達(dá)到甚至對(duì)于 C 語言都直接了當(dāng)?shù)氖虑?。而其?shí)“界面”和“實(shí)現(xiàn)”的分離,并不需要把所有函數(shù)都放進(jìn)對(duì)象里。另外的一些概念,比如繼承,重載,其實(shí)帶來的問題比它們解決的還要多。

“面向?qū)ο蠓椒?rdquo;的過度使用,已經(jīng)開始引起對(duì)整個(gè)業(yè)界的負(fù)面作用。很多公司里的程序員喜歡生搬硬套一些不必要的設(shè)計(jì)模式,其實(shí)什么好事情也沒干,只是使得程序冗長(zhǎng)難懂。不得不指出,《Design Patterns》這本書,是這很大一部分復(fù)雜性的罪魁禍?zhǔn)住2恍业氖?,如此膚淺,毫無內(nèi)容,偷換概念的書籍,居然被很多人捧為經(jīng)典。

那么如何看待具備高階函數(shù)的面向?qū)ο笳Z言,比如 Python,JavaScript,Ruby,Scala?當(dāng)然有了高階函數(shù),你可以直截了當(dāng)?shù)谋硎竞芏鄸|西,而不需要使用設(shè)計(jì)模式。但是由于設(shè)計(jì)模式思想的流毒,一些程序員居然在這些不需要設(shè)計(jì)模式的語言里也采用繁瑣的設(shè)計(jì)模式,讓人哭笑不得。所以在學(xué)習(xí)的時(shí)候,最好不要用這些語言,以免受到不必要的干擾。到時(shí)候必要的時(shí)候再回來使用它們,就可以取其精華,去其糟粕。

2. 低級(jí)過程式語言 

那么是否 C 這樣的“低級(jí)語言”就會(huì)好一些呢?其實(shí)也不是。很多人推崇 C,因?yàn)樗梢宰屓私咏?ldquo;底層”,也就是接近機(jī)器的表示,這樣就意味著它速度快。這里其實(shí)有三個(gè)問題:

接近“底層”是否對(duì)于初學(xué)者是好事?“速度快的語言”是什么意思?接近底層的語言是否一定速度快?

對(duì)于第一個(gè)問題,答案是否定的。其實(shí)編程最重要的思想是高層的語義(semantics)。語義構(gòu)成了人關(guān)心的問題以及解決它們的算法。而具體的實(shí)現(xiàn)(implementation),比如一個(gè)整數(shù)用幾個(gè)字節(jié)表示,雖然還是重要,但卻不是至關(guān)重要的。如果把實(shí)現(xiàn)作為學(xué)習(xí)的主要目標(biāo),就本末倒置了。因?yàn)閷?shí)現(xiàn)是可以改變的,而它們所表達(dá)的本質(zhì)卻不會(huì)變。所以很多人發(fā)現(xiàn)自己學(xué)會(huì)的東西,過不了多久就“過時(shí)”了。那就是因?yàn)樗麄儗W(xué)習(xí)的不是本質(zhì),而只是具體的實(shí)現(xiàn)。

其次,談?wù)Z言的“速度”,其實(shí)是一句空話。語言只負(fù)責(zé)描述一個(gè)程序,而程序運(yùn)行的速度,其實(shí)絕大部分不取決于語言。它主要取決于 1)算法 和 2)編譯器的質(zhì)量。編譯器和語言基本是兩碼事。同一個(gè)語言可以有很多不同的編譯器實(shí)現(xiàn),每個(gè)編譯器生成的代碼質(zhì)量都可能不同,所以你沒法說“A 語言比 B 語言快”。你只能說“A 語言的 X 編譯器生成的代碼,比 B 語言的 Y 編譯器生成的代碼高效”。這幾乎等于什么也沒說,因?yàn)?B 語言可能會(huì)有別的編譯器,使得它生成更快的代碼。

我舉個(gè)例子吧。在歷史上,Lisp 語言享有“龜速”的美名。有人說“Lisp 程序員知道每個(gè)東西的值,卻不知道任何事情的代價(jià)”,講的就是這個(gè)事情。但這已經(jīng)是很久遠(yuǎn)的事情了,現(xiàn)代的 Lisp 系統(tǒng)能編譯出非常高效的代碼。比如商業(yè)的 Chez Scheme 編譯器,能在5秒鐘之內(nèi)編譯它自己,編譯生成的目標(biāo)代碼非常高效。它的實(shí)現(xiàn)真的令人驚嘆,因?yàn)樗淖髡?R. Kent Dybvig 幾乎不依賴于任何已有的軟件和設(shè)計(jì)。這個(gè)編譯器從最初的 parser,到宏擴(kuò)展,語義分析,寄存器分配,各種優(yōu)化,…… 一直到匯編器,函數(shù)庫,全都是他一個(gè)人寫的。它可以直接把 Scheme 程序編譯到多種處理器的機(jī)器指令,而不通過任何第三方軟件。它內(nèi)部的一些算法,其實(shí)比開源的 LLVM 之類的先進(jìn)很多。但是由于是商業(yè)軟件,這些算法一直被作為機(jī)密沒有發(fā)表。

另外一些函數(shù)式語言也能生成高效的代碼,比如 OCaml。在一次程序語言暑期班上,Cornell 的 Robert Constable 教授講了一個(gè)故事,說是他們用 OCaml 重新實(shí)現(xiàn)了一個(gè)系統(tǒng),結(jié)果發(fā)現(xiàn) OCaml 的實(shí)現(xiàn)比原來的 C 語言實(shí)現(xiàn)快了 50 倍。經(jīng)過 C 語言的那個(gè)小組對(duì)算法多次的優(yōu)化,OCaml 的版本還是快好幾倍。這里的原因其實(shí)在于兩方面。第一是因?yàn)楹瘮?shù)式語言把程序員從底層細(xì)節(jié)中解脫出來,讓他們能夠迅速的實(shí)現(xiàn)和修改自己的想法,所以他們能夠迅速的找到更好的算法。第二是因?yàn)?OCaml 有高效的編譯器實(shí)現(xiàn),使得它能生成很好的代碼。

從上面的例子,你也許已經(jīng)可以看出,其實(shí)接近底層的語言不一定速度就快。因?yàn)榫幾g器這種東西其實(shí)可以有很高級(jí)的“智能”,甚至可以超越任何人能做到的底層優(yōu)化。但是編譯器還沒有發(fā)展到可以代替人來制造算法的地步。所以現(xiàn)在人需要做的,其實(shí)只是設(shè)計(jì)和優(yōu)化自己的高層算法。

3. 高級(jí)過程式語言

很早的時(shí)候,國(guó)內(nèi)計(jì)算機(jī)系學(xué)生的第一門編程課都是 Pascal。Pascal 是很好的語言,可是很多人當(dāng)時(shí)都沒有意識(shí)到。大一的時(shí)候,我的 Pascal 老師對(duì)我們說:“我們學(xué)校的教學(xué)太落后了。別的學(xué)校都開始教 C 或者 C++ 了,我們還在教 Pascal。”現(xiàn)在真正理解了程序語言的設(shè)計(jì)原理以后我才真正的感覺到,原來 Pascal 是比 C 和 C++ 設(shè)計(jì)更好的語言。

它不但把人從底層細(xì)節(jié)里解脫出來,沒有面向?qū)ο蟮乃季S枷鎖,而且含有函數(shù)式語言的一些特征(比如可以嵌套函數(shù)定義)。可是由于類似的誤解和誤導(dǎo),Pascal 這樣的語言已經(jīng)幾乎沒有人用了。這并不很可惜,因?yàn)樗木?,其?shí)已經(jīng)存在于像 Scheme 這樣的函數(shù)式語言里。Scheme 也有賦值語句,所以它實(shí)質(zhì)上含有 Pascal 的所有功能。所以現(xiàn)在的含有賦值語句的函數(shù)式語言,可以被看作是是高級(jí)過程式語言的“改良版本”。

4. 函數(shù)式語言

函數(shù)式語言相對(duì)來說是當(dāng)今最好的設(shè)計(jì),因?yàn)樗鼈儾坏屓藢W⒂谒惴ê蛯?duì)問題的解決,而且沒有面向?qū)ο笳Z言那些思維的限制。但是需要注意的是并不是每個(gè)函數(shù)式語言的特性都是好東西。它們的支持者們經(jīng)常把缺點(diǎn)也說成是優(yōu)點(diǎn),結(jié)果它們其實(shí)還是被掛上一些不必要的枷鎖。比如 OCaml 和 SML,因?yàn)樗鼈兊念愋拖到y(tǒng)里面有很多不成熟的設(shè)計(jì),導(dǎo)致你需要記住太多不必要的限制。

很多人推崇“純函數(shù)式”語言(比如 Haskell,Clean),而極力反對(duì)其它的帶有“賦值”語句的語言(比如 Scheme 和 ML)。這其中的依據(jù)其實(shí)是站不住腳的。如果你寫過一個(gè)函數(shù)式語言的編譯器,你就會(huì)了解如何把一個(gè)純函數(shù)式語言翻譯成機(jī)器指令。這些高級(jí)的編譯器變換(比如 CPS 和 ANF),其實(shí)在本質(zhì)上揭示了純函數(shù)式語言的本質(zhì)。它們其實(shí)與帶有賦值語句的語言沒有本質(zhì)上的區(qū)別,但是由于沒有賦值語句,一些事情必須拐彎抹角的實(shí)現(xiàn)。理智的使用局部變量或者數(shù)組的賦值,會(huì)使程序更加簡(jiǎn)單,容易理解,甚至更加高效。

5. 邏輯式語言

邏輯式語言(比如 Prolog)是一種超越函數(shù)式語言的新的思想,所以需要一些特殊的訓(xùn)練。邏輯式語言寫的程序,是能“反向運(yùn)行”的。普通程序語言寫的程序,如果你給它一個(gè)輸入,它會(huì)給你一個(gè)輸出。但是邏輯式語言很特別,如果你給它一個(gè)輸出,它可以反過來運(yùn)行,給你所有可能的輸入。其實(shí)通過很簡(jiǎn)單的方法,可以順利的把程序從函數(shù)式轉(zhuǎn)換成邏輯式的。但是邏輯式語言一般要在“pure”的情況下(也就是沒有復(fù)雜的賦值操作)才能反向運(yùn)行。所以學(xué)習(xí)邏輯式語言最好是從函數(shù)式語言開始,在理解了遞歸,模式匹配等基本的函數(shù)式編程技巧之后再來看 Prolog,就會(huì)發(fā)現(xiàn)邏輯式編程簡(jiǎn)單了很多。

從何開始

可是學(xué)習(xí)編程總要從某種語言開始。那么哪種語言呢?其實(shí)每種語言都有自己的問題,以至于在我未來的書里,會(huì)使用一種非常簡(jiǎn)單的語言,它含有所有語言的精髓,卻不帶有多余的東西??墒窃谖彝瓿蛇@本書之前,我想先推薦一兩個(gè)現(xiàn)成的語言。

就我的觀點(diǎn),首先可以從 Scheme 入門,然后學(xué)習(xí)一些 Haskell (但不是全部),之后其它的也就觸類旁通了。你并不需要學(xué)習(xí)它們的所有細(xì)枝末節(jié),而只需要學(xué)習(xí)最精華的部分。所有剩余的細(xì)節(jié),會(huì)在實(shí)際使用中很容易的被填補(bǔ)上。我后面會(huì)提一下哪些是精華的,哪些是最開頭沒必要學(xué)的。

從 Scheme(而不是 Haskell)作為入門的第一步,是因?yàn)椋?/p>

Scheme 沒有像 Haskell 那樣的靜態(tài)類型系統(tǒng) (static type system)。并不是說靜態(tài)類型不好,但是我不得不說,Haskell 那樣的靜態(tài)類型系統(tǒng),還遠(yuǎn)遠(yuǎn)沒有發(fā)展到可以讓人可以完全的寫出符合事物本質(zhì)的程序來。比如,一些重要的概念比如 Y combinator,沒法用 Haskell 直接寫出來。當(dāng)然你可以在 Haskell 里面使用作用類似 Y combinator 的東西(比如 fix,或者利用它的 laziness),但是這些并不揭示遞歸的本質(zhì),你只是在依靠 Haskell 已經(jīng)實(shí)現(xiàn)的遞歸來進(jìn)行遞歸,而不能實(shí)際的體會(huì)到遞歸是如何產(chǎn)生的。而用 Scheme,你可以輕松的寫出 Y combinator,并且實(shí)際的投入使用。

Scheme 不需要 monad。Haskell是一個(gè)“純函數(shù)式” (purely functional) 的語言,所有的“副作用”(side-effect),比如打印字符到屏幕,都得用一種故作高深的概念叫 monad 實(shí)現(xiàn)。這種概念其實(shí)并不是本質(zhì)的,它所有的功能都可以通過“狀態(tài)傳遞” (state passing) 來實(shí)現(xiàn)。通過寫狀態(tài)傳遞程序,你可以清楚的看到 monad 的本質(zhì)??梢哉f monad 是 Haskell 的一個(gè)“設(shè)計(jì)模式”。過早的知道這個(gè)東西,并不有助于理解函數(shù)式程序設(shè)計(jì)的本質(zhì)。

那么為什么又要學(xué) Haskell?那是因?yàn)?Haskell 含有 Scheme 缺少的一些東西,并且沒有 Scheme 設(shè)計(jì)上的一些問題。比如:

模式匹配:Scheme 沒有一個(gè)標(biāo)準(zhǔn)的,自然的模式匹配(pattern matching) 系統(tǒng),而 Haskell 的模式匹配是一個(gè)優(yōu)美的實(shí)現(xiàn)。也有些 Scheme 的擴(kuò)展實(shí)現(xiàn)(比如 Racket)具有相當(dāng)好的模式匹配機(jī)制。

類型:Scheme 把所有不是 #f (false)的值都作為 true,這是不對(duì)的。Haskell 里面的 Boolean 就只有兩個(gè)值:True 和 False。Scheme 程序員聲稱這樣可以寫出簡(jiǎn)潔的代碼,因?yàn)?(or x y z) 可以返回一個(gè)具體的值,而不只是一個(gè)布爾變量。但是就為了在少數(shù)情況下可以寫出短一點(diǎn)的代碼,是否值得付出如此沉痛的代價(jià)?我看到這個(gè)設(shè)計(jì)帶來了很多無需有的問題。

宏系統(tǒng):宏 (macro) 通常被認(rèn)為是 Lisp 系列語言的一個(gè)重要優(yōu)點(diǎn)。但是我要指出的是,它們并不是必要的,至少對(duì)于初學(xué)者是這樣。其實(shí)如果一個(gè)語言的語義設(shè)計(jì)好了,你會(huì)幾乎不需要宏。因?yàn)楹甑谋举|(zhì)是讓程序員可以自己修改語言的設(shè)計(jì),添加新的構(gòu)造。可是宏的主要缺點(diǎn)是,它把改變語言這種極其危險(xiǎn)的“權(quán)力”給人濫用了。其實(shí)只有極少數(shù)的人具有改變一個(gè)語言所需的智慧和經(jīng)驗(yàn)。如果讓普通程序員都能使用宏,那么程序?qū)⒆兊梅浅ky以理解。所以其實(shí)一般程序員都不需要學(xué)習(xí)宏的使用,也不必為略過這個(gè)東西而產(chǎn)生負(fù)罪感。等你進(jìn)步到可以設(shè)計(jì)自己的程序語言,你自然會(huì)明白宏是什么東西。

(注意,這些是我自己的觀點(diǎn),并不代表 Scheme 設(shè)計(jì)者們的觀點(diǎn)。)

推薦的書籍

《The Little Schemer》:我覺得 Dan Friedman 的 The Little Schemer (TLS) 是目前最好,最精華的編程入門教材。它的前身叫《The Little Lisper》。很多資深的程序語言專家都是從這本書學(xué)會(huì)了 Lisp。雖然它叫 "The Little Schemer",但它并不使用 Scheme 所有的功能,而是忽略了上面提到的 Scheme 的毛病,直接進(jìn)入最關(guān)鍵的主題:遞歸和它的基本原則。這本書不但很薄,很精辟,而且相對(duì)于其他編程書籍非常便宜(在美國(guó)才賣 $23)。

《SICP》:The Little Schemer 其實(shí)是比較難的讀物,所以我建議把它作為下一步精通的讀物。Structure and Interpretation of Computer Programs 比較適合作為第一本教材。但是我需要提醒的是,你最多只需要看完前三章。因?yàn)閺牡谒恼麻_始,作者開始實(shí)現(xiàn)一個(gè) Scheme 解釋器,但是作者的實(shí)現(xiàn)并不是最好的方式。你可以從別的地方更好的學(xué)到這些東西。具體在哪里學(xué),我還沒想好(也許我自己寫個(gè)教學(xué)也說不定)。不過也許你可以看完 SICP 第一章之后就可以開始看 TLS。

《A Gentle Introduction to Haskell》:對(duì)于 Haskell,我最開頭看的是 A Gentle Introduction to Haskell,因?yàn)樗貏e短小。當(dāng)時(shí)我已經(jīng)會(huì)了 Scheme,所以不需要再學(xué)習(xí)基本的函數(shù)式語言的東西。我從這個(gè)文檔學(xué)到的只不過是 Haskell 對(duì)于類型和模式匹配的概念。Real World Haskell 是一本流行的教材,但是它試圖包羅萬象,所以很多地方過于冗長(zhǎng)。最根本的函數(shù)式編程概念,還是 TLS 講的透徹。

過度到面向?qū)ο笳Z言

那么如果從函數(shù)式語言入門,如何過渡到面向?qū)ο笳Z言呢?畢竟大部分的公司用的是面向?qū)ο笳Z言。如果你真的學(xué)會(huì)了函數(shù)式語言,你真的會(huì)發(fā)現(xiàn)面向?qū)ο笳Z言已經(jīng)易如反掌。函數(shù)式語言的設(shè)計(jì)比面向?qū)ο笳Z言簡(jiǎn)單和強(qiáng)大很多,而且?guī)缀跛械暮瘮?shù)式語言教材(比如 SICP)都會(huì)教你如何實(shí)現(xiàn)一個(gè)面向?qū)ο笙到y(tǒng)。

你會(huì)深刻的看到面向?qū)ο蟮谋举|(zhì)以及它存在的問題,所以你會(huì)很容易的搞清楚怎么寫面向?qū)ο蟮某绦?,并且?huì)發(fā)現(xiàn)一些竅門來避開它們的局限。你會(huì)發(fā)現(xiàn),即使在實(shí)際的工作中必須使用面向?qū)ο笳Z言,也可以避免面向?qū)ο蟮乃季S方式,因?yàn)槊嫦驅(qū)ο蟮乃枷霂淼拇蟛糠质腔靵y和冗余。

深入本質(zhì)和底層

那么是不是完全不需要學(xué)習(xí)底層呢?當(dāng)然不是。但是一開頭就學(xué)習(xí)底層硬件,就會(huì)被紛繁復(fù)雜的硬件設(shè)計(jì)蒙蔽頭腦,看不清楚本質(zhì)上簡(jiǎn)單的原理。

在學(xué)會(huì)高層的語言之后,可以進(jìn)行語義學(xué)和編譯原理的學(xué)習(xí)。簡(jiǎn)言之,語義學(xué) (semantics) 就是研究程序的符號(hào)表示如何對(duì)機(jī)器產(chǎn)生“意義”,通常語義學(xué)的學(xué)習(xí)包含 lambda calculus 和各種解釋器的實(shí)現(xiàn)。編譯原理 (compilation) 就是研究如何把高級(jí)語言翻譯成低級(jí)的機(jī)器指令。

編譯原理其實(shí)包含了計(jì)算機(jī)的組成原理,比如二進(jìn)制的構(gòu)造和算術(shù),處理器的結(jié)構(gòu),內(nèi)存尋址等等。但是結(jié)合了語義學(xué)和編譯原理來學(xué)習(xí)這些東西,會(huì)事半功倍。因?yàn)槟銜?huì)直觀的看到為什么現(xiàn)在的計(jì)算機(jī)系統(tǒng)會(huì)設(shè)計(jì)成這個(gè)樣子:為什么處理器里面有寄存器(register),為什么需要堆棧(stack),為什么需要堆(heap),它們的本質(zhì)是什么。

這些甚至是很多硬件設(shè)計(jì)者都不明白的問題,所以它們的硬件里經(jīng)常含有一些沒必要的東西。因?yàn)樗麄儾焕斫庹Z義,所以經(jīng)常不明白他們的硬件到底需要哪些部件和指令。但是從高層語義來解釋它們,就會(huì)揭示出它們的本質(zhì),從而可以讓你明白如何設(shè)計(jì)出更加優(yōu)雅和高效的硬件。

這就是為什么一些程序語言專家后來也開始設(shè)計(jì)硬件。比如 Haskell 的創(chuàng)始人之一 Lennart Augustsson,后來設(shè)計(jì)了 BlueSpec,一種高級(jí)的硬件描述語言,可以 100% 的合成 (synthesis) 為硬件電路。Scheme 也被廣泛的使用在硬件設(shè)計(jì)中,比如 Motorola,Cisco 和曾經(jīng)的 Transmeta,它們的芯片設(shè)計(jì)里面含有很多 Scheme 程序。

這基本上就是我對(duì)學(xué)習(xí)程序語言的初步建議。

原文鏈接:http://kb.cnblogs.com/page/152132/

責(zé)任編輯:張偉 來源: 博客園
相關(guān)推薦

2012-08-13 09:40:12

語言編程語言程序語言

2017-07-10 17:00:24

程序語言語言特性

2009-03-02 09:40:13

程序員程序語言開發(fā)

2011-08-25 10:15:02

Lua安裝函數(shù)

2011-05-19 14:00:51

PHP單引號(hào)雙引號(hào)

2014-02-25 10:35:37

神經(jīng)學(xué)程序語言

2011-07-15 17:05:14

2012-06-27 10:28:12

編程語言語言學(xué)習(xí)多門語言

2014-08-01 10:39:52

大數(shù)據(jù)程序語言

2019-04-19 08:15:19

微軟瀏覽器Windows

2014-08-12 09:54:35

Web語言編程語言

2015-08-17 16:22:36

大數(shù)據(jù)

2011-08-25 10:24:27

Lua

2014-08-01 10:06:36

大數(shù)據(jù)

2012-05-28 09:34:36

編程語言WEB編程

2017-08-07 15:19:30

編程語言快速

2021-01-16 11:44:46

編程語言開發(fā)

2014-06-24 15:36:47

程序語言AppSwift

2021-10-26 16:25:25

編程語言JavaPython

2009-08-14 09:50:24

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)