編程語言的進(jìn)化
早上讀到了一篇文章《Lisp的永恒之道》 這一篇文章解決了我一直以來對(duì)Lisp編程語言的疑惑,加深了對(duì)DSL(領(lǐng)域編程語言),同時(shí)對(duì)編程語言的理解也越來越深入。寫一篇文章的目的就是從主要編程語言的進(jìn)化來看看編程語言發(fā)展的過程以及背后的設(shè)計(jì)哲學(xué),當(dāng)然,這個(gè)只是我自己的認(rèn)識(shí),如果有不足之處,請(qǐng)博友指教。
機(jī)器語言
最早的編程語言是卡帶,也就是機(jī)器語言,這種語言沒有語義和語法,操作符和數(shù)據(jù)混合在一起,偏向于具體的設(shè)備,依賴覺得硬件。
匯編語言
隨后,匯編語言就出現(xiàn)了,匯編語言定義了基本的語法結(jié)構(gòu),定義了操作符和數(shù)據(jù)類型,但是匯編語言還是針對(duì)特定的硬件編程,比如cpu,我記得大學(xué)的時(shí)候?qū)W習(xí)的就是8086匯編語言程序設(shè)計(jì),這個(gè)就是針對(duì)intel 8086cpu的編程語言而設(shè)計(jì),如果cpu是80386,那么就必須在對(duì)80386的cpu進(jìn)行編程,可移植性非常差。如果針對(duì)每一個(gè)cpu就要重新寫整一套代碼,那么將會(huì)是多么復(fù)雜的事情,困難度不可想象。
C語言
對(duì)于匯編語言的問題,主要要解決跨硬件平臺(tái),那么怎么解決這個(gè)問題了,對(duì)啦,添加一個(gè)抽象層,這個(gè)就是硬件抽象層,它隱藏了特定平臺(tái)的硬件接口細(xì)節(jié),為操作系統(tǒng)提供虛擬硬件平臺(tái),使其具有硬件無關(guān)性,可在多種平臺(tái)上進(jìn)行移植。相當(dāng)于提供統(tǒng)一的api 比如C語言printf函數(shù),打印字符串,由于每個(gè)終端設(shè)備的類型和型號(hào)都不一樣,需要在適配到每個(gè)終端設(shè)備上,那么通過一個(gè)終端虛擬硬件,由它進(jìn)行各個(gè)終端差異的屏蔽,提供統(tǒng)一的對(duì)外接口,有點(diǎn)類似適配器模式。用C語言寫出來的程序。雖然這樣簡(jiǎn)化了操作硬件的這種復(fù)雜行,但是直接寫操作虛擬硬件的代碼也是很苦逼的事情,這樣就出現(xiàn)了系統(tǒng)內(nèi)核,用來提供更高一層的抽象,所以C語言操作硬件的函數(shù)都會(huì)調(diào)用系統(tǒng)內(nèi)核,由系統(tǒng)內(nèi)核再去調(diào)用具體的虛擬終端設(shè)備。這個(gè)就和特定的操作系統(tǒng)有關(guān)了,C語言編譯器編譯出來的代碼就和操作系統(tǒng)進(jìn)行關(guān)聯(lián)。所以C語言程序很難做到跨操作系統(tǒng)平臺(tái),因?yàn)槊總€(gè)操作系統(tǒng)都提供私有函數(shù),并且編譯出來的二進(jìn)制代碼也是不一樣的,跨平臺(tái)基本不可能。
高級(jí)語言:java,.net
為了解決C語言的跨平臺(tái)的問題,可以考慮再在操作系統(tǒng)這一層添加一個(gè)抽象。那么就出現(xiàn)了java和.net這樣的編程語言。java通過實(shí)現(xiàn)一個(gè)jvm虛擬機(jī),屏蔽了各個(gè)操作系統(tǒng)的差異,同時(shí)定義了一個(gè)標(biāo)準(zhǔn)的目標(biāo)代碼(class文件),只要class文件滿足jcp定義的規(guī)范,就可以被jvm執(zhí)行。這就解決了兩個(gè)問題,目標(biāo)代碼格式固定,這個(gè)平臺(tái)都一樣,函數(shù)調(diào)用都一樣,都和jvm打交道。這樣就實(shí)現(xiàn)了跨越操作系統(tǒng)平臺(tái)。但是還存在一個(gè)問題,jvm的實(shí)現(xiàn)只能夠獲取各個(gè)操作系統(tǒng)公共的部分進(jìn)行抽象,但是有一些操作系統(tǒng)私有的個(gè)性化是無法屏蔽的,只能通過開通一個(gè)小后門,讓開發(fā)者能夠開發(fā)基于操作系統(tǒng)的native實(shí)現(xiàn)。
DSL領(lǐng)域編程語言
好了,編程語言發(fā)展到這一層,已經(jīng)非常高級(jí)了,對(duì)于開發(fā)者來說,已經(jīng)夠簡(jiǎn)單了。不需要硬件只是,不需要懂操作系統(tǒng)知識(shí)。如果在繼續(xù)發(fā)展會(huì)怎么樣,對(duì)啦,是不是可以跨越編程語言。還有,編程語言一般都是語法和語義綁定在一起的,比如 int c = a + b 這一條賦值語句,我們知道要把 a 和 b相加 賦予 c ,相當(dāng)于知道語法,就知道語義了,那么是不是可以把語義 和 語法 分開 ?
語義:
- define c = add(b,c)
或者
- <opteration name="add" result="c"><paramparam="a,b"/></opteration>
那么轉(zhuǎn)化為 java語言 就是 int c = a + b; 轉(zhuǎn)化為javasrpit var c = a + b 等等
相當(dāng)于what 和 how 分開,就是說 我要做什么 和 我怎么做 這一層在區(qū)分開來。目前我們使用的比較多的就是maven
maven通過自己的一套語義,定義了整個(gè)構(gòu)建的過程。我只定義了怎么做,通過xml這一套語法來定義,但是具體怎么做我通過一個(gè)解釋層來實(shí)現(xiàn),同時(shí)也可以用不同的語言,可能在java平臺(tái)上,我用java語言來實(shí)現(xiàn),在.net平臺(tái),我用.net來實(shí)現(xiàn)。
其中大名頂頂?shù)?facebook的 Thrift框架就是這種設(shè)計(jì)思想,通過自己定義的一套語言,定了一個(gè)分布式服務(wù)框架,通過自己的解釋器,把自己定義的解釋成為不同的語言實(shí)現(xiàn)。
但是由于領(lǐng)域語言的語義定義的規(guī)則和模式都不一樣,對(duì)于每個(gè)不同的領(lǐng)域,都有自己的DSL,比如是ant,我就必須學(xué)習(xí)一下整個(gè)ant的規(guī)則,比如maven也需要重新開始學(xué)習(xí)。
目前很多語言轉(zhuǎn)化服務(wù),比如目前把java寫的語言轉(zhuǎn)化為obejct-c和windows的云服務(wù),原理和上面類似,應(yīng)該都是先轉(zhuǎn)化為一套中間語言,然后轉(zhuǎn)化成為各個(gè)實(shí)際的特性語言。
未來想象
隨著DSL語言的快速發(fā)展,我在想 未來是不是會(huì)把DSL也統(tǒng)一起來,定義一套通用的規(guī)則和規(guī)范,找出每個(gè)領(lǐng)域特性部分,進(jìn)行抽象,形成一種統(tǒng)一的開發(fā)語言。比如web編程,只需要web方面的DSL語言就可以了,不需要在學(xué)習(xí)python,php,jsp,asp等等,在數(shù)據(jù)庫操作方面也一樣,不需要在了解各個(gè)平臺(tái)具體連接數(shù)據(jù)庫的方式以及代碼實(shí)現(xiàn),用統(tǒng)一的數(shù)據(jù)操作DSL就可以了。這個(gè)想法比較大,也是扯扯淡的,不過還是希望未來的某一天,編程語言會(huì)統(tǒng)一,不過現(xiàn)在越來越有這個(gè)趨勢(shì)了,各個(gè)語言都在添加其他語言的特性,增強(qiáng)自己的特性,以后各個(gè)語言都變的越來越類似,功能也越來越雷同,***需要考慮的是語言性能問題,但是隨著硬件的發(fā)展,除非某一個(gè)特定的領(lǐng)域,大部分應(yīng)用在語言層面的性能應(yīng)該會(huì)忽略。
通過編程語言的進(jìn)化,起始發(fā)現(xiàn)背后的思想都是一樣的,原話我忘記是怎么說的,大概意思是:任何兩個(gè)系統(tǒng)之間的復(fù)雜性,都可以通過添加一個(gè)抽象層要屏蔽。整個(gè)編程語言的進(jìn)化也都說明了這個(gè)問題。
原文鏈接:http://www.cnblogs.com/aigongsi/archive/2012/09/28/2706604.html