今天碰巧討論起來編程語言。好像最近很流行的一個(gè)話題,包括lisp和haskell的再一次又一次悄然流行。
PS:這些是我很一些同學(xué)一次討論的總結(jié),可能有我沒有說清楚的地方,也有可能是我沒有理解對的地方,如果有哪里寫的不對,歡迎大家指正。
我的風(fēng)格:
首先我不會haskell和lisp,請大家聯(lián)想一下一個(gè)不用emacs的人。
選擇策略:
我所長久使用的,或者說是擅長的是匯編,包括幾種結(jié)構(gòu)的匯編。當(dāng)然后來出于敏捷的考慮我會用C,如果充滿了網(wǎng)絡(luò)應(yīng)用,正則表達(dá),文件操作這種功能性比較強(qiáng)而且要頻繁的和操作系統(tǒng)打交道而不是cpu的時(shí)候,我會用python,如果是以網(wǎng)絡(luò)操作為主的話那么用perl。
風(fēng)格源自匯編:
但是我無論用哪種編程語言你可以看到一種非常統(tǒng)一風(fēng)格就是來自于匯編的風(fēng)格,非常強(qiáng)的指令邏輯順序風(fēng)格。最簡單的一個(gè)例子就是goto的使用,因?yàn)檫@個(gè)和匯編中的jmp系列命令是一致的。我不會用非常C的風(fēng)格,比如宏定義,switch 以及while,甚至我的C中嵌入?yún)R編都是很經(jīng)常的事情。我寫c程序唯一看起來像C的地方,就是指針和for,滿篇的指針運(yùn)算因?yàn)檫@個(gè)和匯編中的地址操作是一致的。我會用指針來完成switch while 等操作,我所使用的C無非是[for + 指針 + goto + if +中斷]沒了。還有一個(gè)特別明顯的特征就是我特別愛用中斷,這個(gè)是國內(nèi)學(xué)生不太愿意用的東西,其實(shí)特別好用。因?yàn)閰R編和系統(tǒng)之間交互的時(shí)候就是用中斷實(shí)現(xiàn)的??偨Y(jié)一句話,我的風(fēng)格是用硬件開發(fā)工具寫算法。夠奇葩吧。
思維模式:
我能理解的是中斷,地址,以及指令過程。比如信號和信號槽我就理解成為一種軟中斷實(shí)現(xiàn),類似的還有時(shí)刻表cron,這個(gè)是時(shí)鐘中斷的一種派生,指針是地址的一種實(shí)現(xiàn),重載是函數(shù)指針的一種實(shí)現(xiàn)。我所不能理解的就是迭代,這個(gè)常常使得別人對我產(chǎn)生誤解,認(rèn)為我擅長計(jì)算機(jī)工程而不是計(jì)算機(jī)科學(xué),其實(shí)不然,我是按照計(jì)算數(shù)學(xué)的思路在寫程序,而不是按照集合論的想法在寫程序,僅此而已。
缺陷:
我寫的程序其實(shí)針對性非常強(qiáng),即使C以移植性著稱,但是這個(gè)是一個(gè)狹義的移植性概念。
在我看來
編程語言的不同,是編程模型的不同,如果想掌握一門編程語言,首先要弄清楚編程模型是什么。
比如:
*匯編的編程模型是cpu,
寫匯編的時(shí)候經(jīng)常要拿著datasheet,然后查閱時(shí)序圖,時(shí)序圖就是基本的工具,用這些工具構(gòu)建你想要實(shí)現(xiàn)的功能。需要和外部交互的時(shí)候還需要知道io map是怎么樣的,如果有bios這樣管理io的子系統(tǒng)的時(shí)候那么你只要弄清楚bios給你提供的服務(wù)就可以了。匯編和操作系統(tǒng)之間交互是通過中斷來實(shí)現(xiàn)的,也就是仿真一種硬件行為,這個(gè)行文叫做軟中斷,然后操作系統(tǒng)會守護(hù)這些中斷信號然后作出反映。
*C的編程模型是內(nèi)存,
在用C寫成的時(shí)候大部分的時(shí)間是和內(nèi)存打交道,不需要(但是有權(quán)利)管理cpu內(nèi)部的寄存以及其他的一些具體部件,那些都有一個(gè).h文件統(tǒng)一管理和抽象。然后你只要關(guān)心內(nèi)存就可以了。和外部通信的時(shí)候也是將那些功能映射到內(nèi)存地址了。C和操作系統(tǒng)之間的橋梁只有標(biāo)準(zhǔn)IO就是stdin stdout 和stderr,由于一切文件化的抽象,能用的指令也只有read 和write。當(dāng)然你還要用ioctl先設(shè)置一個(gè)合適的工作狀態(tài)。當(dāng)你寫的本身就是內(nèi)核的時(shí)候,那些變量都可以直接調(diào)用的,比如全局時(shí)間。
*python的編程模型是應(yīng)用,
其實(shí)我不太會用python,我只是說說我是這么用的,python可能是各種功能實(shí)現(xiàn)的一種抽象,如果有那么一個(gè)應(yīng)用無論是什么語言編寫,無論是如何執(zhí)行,那么他一定可以有(或是已經(jīng)有)python接口了,你調(diào)用這種接口,然后建立一個(gè)實(shí)體,這個(gè)實(shí)體就是一個(gè)應(yīng)用的抽象。比如我可以創(chuàng)建一個(gè)webkit的實(shí)體,然后這個(gè)實(shí)體就可以有url這個(gè)變量,填好后,就可以用open()這個(gè)函數(shù),然后從context里面就能得到瀏覽結(jié)果了。python和操作系統(tǒng)之間的交互很靈活,可以通過os 這個(gè)抽象,或是exec等等。當(dāng)然管道也是一個(gè)利器,可以通過popen取出程序執(zhí)行過程中的標(biāo)準(zhǔn)io里面的內(nèi)容。
*perl還不是很會,其實(shí)我一直拿perl當(dāng)python的網(wǎng)絡(luò)加+正則表達(dá)加強(qiáng)版,等以后我有時(shí)間了,再學(xué)習(xí)一下,再加上這一段。
那么,我寫程序的風(fēng)格貼近硬件,但是其實(shí)不怎么本質(zhì)。需要大量的計(jì)算數(shù)學(xué),而不是數(shù)學(xué)。還有另外一類更本質(zhì)的編程,更數(shù)學(xué)的編程語言,是基于計(jì)算機(jī)理論的,也就是圖靈理論。這些編程語言是面向計(jì)算過程的包括:遞歸,λ演算和圖靈機(jī),這三個(gè)是等價(jià)的,所使用的是邏輯數(shù)學(xué)+集合論,所討論的問題是可計(jì)算問題。這些程序的移植性非常強(qiáng),即使沒有操作系統(tǒng)。他們不需要操作系統(tǒng),編譯器或者解釋器完成的任務(wù)就是將各種不同的圖靈機(jī)物理實(shí)現(xiàn)轉(zhuǎn)化成基本操作符,這里已經(jīng)不要求物理實(shí)現(xiàn)是計(jì)算機(jī)了,物理實(shí)現(xiàn)有可能是各種形態(tài)的。他們描述的是計(jì)算的本質(zhì)。
*LISP 、Haskell 編程模型是命題
那么,所編寫的程序其實(shí)就是證明過程,純函數(shù)編程語言,基本操作就是λ演算,每一個(gè)計(jì)算原子就是一個(gè)λ算式,沒有語句。基本編程結(jié)構(gòu)是遞歸。LISP抽象了7種基本操作符也就是7條公理。遞歸的用這些基本公理,證明命題是可以計(jì)算的。指導(dǎo)思想是邏輯數(shù)學(xué)和集合論。沒有side effect,也就是說不能修改函數(shù)以外的變量,也不能修改代入的變量,純迭代,只有返回值,由于嚴(yán)格的迭代要求所以可以在代碼運(yùn)行的過程中,進(jìn)行修改代碼。和系統(tǒng)交互使用的是actions這個(gè)atom,由于要保持計(jì)算的過程的單純性,盡量將IO降到最低限度。C python都有嵌入λ算子功能是為了實(shí)現(xiàn)異步回調(diào)算法。