為什么會(huì)有這么多種程序設(shè)計(jì)語言?
傳說人類建造通天塔觸怒上帝,上帝施法使人類語言混亂彼此之間無法交流。這就是說各種各樣的語言其實(shí)就是禍亂之源——只會(huì)導(dǎo)致交流的不便。可是看看如今的程 序設(shè)計(jì)語言的數(shù)量,你會(huì)懷疑人類是否又在造“通天塔”了?真的有這么多語言的必要嗎?我到底要學(xué)習(xí)多少種程序設(shè)計(jì)語言才夠用呢?
根據(jù)維基的資料,可以稱得上相對(duì)“主流”(有人用、有文檔)的程序設(shè)計(jì)語言至少有600種, 還有大量的商業(yè)化失敗、實(shí)用性不高、語言小眾(這里的“語言”指的是編碼的語言,一般的程序設(shè)計(jì)語言都習(xí)慣用拉丁字母集合或其超集來作為源碼的字符集,也 有用日文、俄文編程、漢語編程的,比如易語言)就難以統(tǒng)計(jì)了(保守估計(jì)可以上萬種),盡管已經(jīng)有了這么多種程序設(shè)計(jì)語言,仍然有大量的人投入了大量的時(shí)間 來研發(fā)新的語言,這難道不是重復(fù)通天塔的故事嗎?
為了解釋“為什么會(huì)有這么多種程序設(shè)計(jì)語言”這個(gè)問題,想讓我們來看一份較新的***編程語言流行榜:
排行榜上排名前十的依次是:C、Java、Object-C、C++、C#、PHP、Python、JavaScript、Perl和VB。下面我會(huì)根據(jù)這份排行榜來回答我們的問題。首先闡述一個(gè)基本觀點(diǎn):程序設(shè)計(jì)語言被創(chuàng)造的目的主要有三個(gè)——實(shí)用目的、學(xué)術(shù)目的、商業(yè)及特殊應(yīng)用需要。且聽一一分解:
一、實(shí)用目的
可以看見在排行榜中,C,Java,C++這樣的語言幾乎是年年穩(wěn)居前五。這些語言的實(shí)用性都是非常高的。讓我們回顧一下C語言的歷史:1973年AT&T的Ken Thompson因?yàn)檠邪l(fā)和維護(hù)操作系統(tǒng)的需要,要求一種高效簡潔的程序設(shè)計(jì)語言,于是在BCPL語言的基礎(chǔ)上創(chuàng)造了C語言。Java、C++等語言也都是在有著類似的高要求的任務(wù)下臨時(shí)創(chuàng)造出來,然后再不斷發(fā)布標(biāo)準(zhǔn)進(jìn)行改進(jìn)的(C語言是為了操作系統(tǒng),Java是為了嵌入式應(yīng)用和網(wǎng)絡(luò)開發(fā)……) 如果現(xiàn)有的輪子不夠好,那么就去自己造一個(gè)輪子,也正是因?yàn)檫@個(gè)特殊的原因,所有這些以實(shí)用為目的的語言都很高效,語法構(gòu)造方法、編程邏輯和配套的編譯技術(shù)都很成功,所以能夠切切實(shí)實(shí)地解決工程上的問題。另外,這些實(shí)用目的語言的語法都很自由(Python因?yàn)?ldquo;明確”、“簡單”的哲學(xué)所以算個(gè)例外),正好符合了不同性格的程序員的需要。另外非常重要的一點(diǎn)是:“決定一種程序設(shè)計(jì)語言是否強(qiáng)大的是這個(gè)語言的庫(標(biāo)準(zhǔn)程序庫、類庫、包、組件、單元、模塊……每種語言都有自己的叫法)而不是程序設(shè)計(jì)語言本身”;這可能會(huì)讓很多人不高興:說實(shí)話,C語言在語言的優(yōu)雅性和友好性上(比如==和=)完全和Ada、Pascal比不了(Ada是軍方人員設(shè)計(jì)的,Pascal是數(shù)學(xué)家設(shè)計(jì)的),但是C語言依然非常流行,這是因?yàn)槟阆胍獙懸粋€(gè)含有系統(tǒng)調(diào)用的程序,用C語言是***選擇,Ada和Pascal這樣的語言想要直接和內(nèi)核交流是很麻煩的。同理也可以解釋C++、Java、Perl等語言的流行,你想要寫多線程的程序用C++的多線程庫和Java的包就行了,你想寫正則表達(dá)式相關(guān)的程序用Perl或者C++ boost庫就好了……懂得不要重復(fù)造輪子是很重要的,遇到不能解決的問題,先去查查資料看有沒有人已經(jīng)寫好了類似的程序,直接把他的函數(shù)抄過來就是了——這恐怕是很多人都會(huì)做的吧?這些實(shí)用性的語言,在長期使用的廣泛的使用過程中積累了大量優(yōu)秀的庫(C++的STL、BOOST和有些編譯器自帶的庫,Object-C專門針對(duì)Mac OS X的庫,F(xiàn)ortran的便于科學(xué)計(jì)算的函數(shù)等等),而且還有越來越多的程序員在不斷增加更好的庫,這些都使這些“語言”越來越強(qiáng)大。
這些程序設(shè)計(jì)語言在發(fā)展過程中既有一些公共的庫(比如文件的I/O),也有一些特有的庫(比如線程庫、RE庫), 這些特有的庫往往是某一語言的***優(yōu)勢,可以說正是這些各自獨(dú)立的庫把不同的語言區(qū)別開來,長此以往,解決某些特定問題時(shí)程序員就傾向使用某一特定語言。 這并不是說這些特有的庫無法移植到其它的語言上,只是由于代碼量巨大,移植是在是個(gè)不小的工程(況且,在某種語言中表述很方便的語言在另一種中就會(huì)難以表 示,比如C語言有很多語言都沒有的顯示指針,在Lazarus項(xiàng)目中,程序員開發(fā)了一個(gè)程序用以把C頭文件自動(dòng)轉(zhuǎn)換成Pascal單元,即使這樣,實(shí)現(xiàn)代碼的量依舊很大,這種源到源的語言翻譯的介紹可以參見龍書的引論部分,不學(xué)編譯原理的請(qǐng)略過)。因?yàn)橛腥绱硕嗟膶S脦欤@些實(shí)用目的語言越來越多也就不稀奇了。
二、學(xué)術(shù)目的
不管什么程序設(shè)計(jì)語言,在本質(zhì)上都不過是機(jī)器級(jí)別的0或1。所謂的高級(jí)語言不過是機(jī)器眼中的胡言亂語(這也正是編譯技術(shù)存在的價(jià)值)。
然而,人不是機(jī)器,也不可能也沒必要成為機(jī)器。創(chuàng)造程序設(shè)計(jì)語言的目的是為程序員服務(wù)的,應(yīng)該說,一個(gè)程序員所用的語言很大程度上決定了他的思維方式——程序設(shè)計(jì)語言本身就是一種嚴(yán)謹(jǐn)?shù)臄?shù)學(xué)模型、一種高效的思維方式。為了說明這個(gè)道理我以一個(gè)物理題為例來解釋:一輛汽車做勻速直線運(yùn)動(dòng),以2m/s的速度經(jīng)過了6m,問汽車用了多少時(shí)間?顯然t=s/v=6/2=3(s),這也可以列方程來解決:設(shè)運(yùn)動(dòng)用時(shí)t s,則 tv=s,即 2t=6,解得t=3,這好像多此一舉。如果把問題稍微“復(fù)雜”一下:一輛汽車以1m/s的初速度做加速為2m/s2的勻加速直線運(yùn)動(dòng),經(jīng)過了6m,問汽車用時(shí)多少時(shí)間?根據(jù)運(yùn)動(dòng)學(xué)公式列方程 V0*t+1/2*a*t2=s,即 1*t+0.5*2*t2=6,解得 t=2,也就是要用2s。又或者可以這樣做:由速度與時(shí)間的關(guān)系可以得到 v(t)=v0+a*t,而
解這個(gè)等式同樣也可以求出t。這個(gè)時(shí)候使用方程就很自然了,用定積分卻顯得多余。從中我們知道什么?人的思維能力是有限的,面對(duì)復(fù)雜的新問題,要么用就用原來老方法麻煩地進(jìn)行計(jì)算,要么提出新的高效的模型來解決問題。不管是算術(shù)、方程還是微積分、傅立葉變換或是其它高級(jí)的數(shù)學(xué)方法、模型都只是一個(gè)簡化問題的抽象層(數(shù)學(xué)家看到了我說這句話恐怕會(huì)很生氣的,但這就是事實(shí)),作為類比,程序設(shè)計(jì)語言就好比這里的數(shù)學(xué)模型,越是復(fù)雜的問題、越是大的規(guī)模(指問題規(guī)模),才越能體現(xiàn)出高級(jí)語言的價(jià)值(有人用過幾十多種語言寫”hello world”,這有什么意義呢?我用機(jī)器語言都能寫hello world)。知道了語言模型對(duì)于思維方式的影響,我們就能解釋這么多語言的學(xué)術(shù)上(或者說是研究上)的目的了:機(jī)器語言/匯編語言意味著程序員專注的是寄存器、內(nèi)存地址、狀態(tài)、位的打開或關(guān)閉,因此思維重在每一條實(shí)際的指令;而C、Pascal這樣的命令式語言注重每一個(gè)“計(jì)算過程”,因此思維重在將計(jì)算方法、算法、數(shù)學(xué)模型表達(dá)出來;而Java、C++這樣的面向?qū)ο蟮某绦蛟O(shè)計(jì)語言,試圖用對(duì)象、類、屬性、方法這些概念來統(tǒng)一的描述算法和數(shù)據(jù)結(jié)構(gòu),OO語言的思維因此能夠重在算法和數(shù)據(jù);還有像Lisp、Haskell、Erlang、Prolog這樣的函數(shù)式、邏輯式語言,強(qiáng)調(diào)的是數(shù)學(xué)的推演、函數(shù)的運(yùn)算、邏輯的證明,我認(rèn)為它們才是最接近人的思維的語言;而像SQL這樣的語言,強(qiáng)調(diào)是“高產(chǎn)出”,它們是對(duì)常用的指令進(jìn)行了簡化、“宏化”(Macronize,本人自己造的一個(gè)詞),它們的思維是“要做什么”而不是“怎么做”;***,是像HTML這類Markup語言(有人說HTML不是程序設(shè)計(jì)語言……)個(gè)人認(rèn)為是一種glue(膠水語言,最有名的glue算是Lua了),它對(duì)文本(比如網(wǎng)頁)的格式進(jìn)行描述,同時(shí)又把JavaScript、Applet等等擴(kuò)展“連接”在一起,它們的思維是“組合”,是怎樣才能協(xié)調(diào)各個(gè)組件、把組件的功能發(fā)揮到***(說起排版不得不提提TeX了,它和HTML的 思維類似,各種開發(fā)好的宏集就是它的“組件”)。***我還想再談一談“學(xué)術(shù)風(fēng)味”很濃的函數(shù)式語言,函數(shù)式語言歷史悠久,但多年以來一直在學(xué)術(shù)界活躍,少 有能夠成功商業(yè)化的,多年來一直處于不溫不火的的狀態(tài)。但隨著今年來編譯技術(shù)的發(fā)展,函數(shù)式語言的執(zhí)行效率已經(jīng)很高了,加上大數(shù)據(jù)時(shí)代對(duì)于大量數(shù)據(jù)處理的 需求、機(jī)器深度學(xué)習(xí)的成熟、現(xiàn)代架構(gòu)計(jì)算機(jī)的發(fā)展,僅僅依靠程序執(zhí)行的單線程性能提升已經(jīng)不能夠滿足實(shí)際需求了,只有并發(fā)和并發(fā)才能滿足這樣的高負(fù)荷計(jì)算 要求,純函數(shù)語言處理起多線程來十分方便,能夠“榨干”處理器的運(yùn)算潛力,這也是近年來Erlang之類的語言大放異彩的重要原因。在現(xiàn)代計(jì)算機(jī)結(jié)構(gòu)和工藝發(fā)展難度大的情況下,這些函數(shù)式語言可能會(huì)成為推動(dòng)計(jì)算力的重要?jiǎng)恿?,這一點(diǎn)可以參見本人的論文《AACOS:基于編譯器和操作系統(tǒng)內(nèi)核的算法設(shè)計(jì)與實(shí)現(xiàn)》(由于版權(quán)的問題,我暫時(shí)不能把論文貼出來:-))。
三、商業(yè)及特殊應(yīng)用需要
(以下言論僅僅是本人個(gè)人觀點(diǎn),沒有任何指責(zé)的意思)
開發(fā)一種編程語言是可以賺錢的,你信嗎?
實(shí)際上開發(fā)一種新的語言意味著建立自己的“統(tǒng)一標(biāo)準(zhǔn)”(說起標(biāo)準(zhǔn)就不得不談高通了,高通從“標(biāo)準(zhǔn)”上撈了多少銀子?),一方面可以方便維護(hù)自己的產(chǎn)品,另一方面可以借助市場地位強(qiáng)迫程序員學(xué)習(xí)某種語言進(jìn)而達(dá)到自己(至少在某一領(lǐng)域)的霸主地位。為什么這么多年以來微軟對(duì)BASIC情有獨(dú)鐘?在DOS時(shí)代,QBASIC——一種BASIC的變種,是每臺(tái)PC上必裝應(yīng)用,也是當(dāng)時(shí)很多人必學(xué)的一種語言,QBASIC無論是從程序執(zhí)行效率還是語言的思維性上都不好,但是因?yàn)槭穷A(yù)裝的,本著“不夠好但夠用”的原則,許多用戶居然湊合下來了(慚愧本人就是從QBASIC開始接觸編程的)!這恐怕和IE用戶如此眾多的原因是異曲同工的吧?就這樣QBASIC居然一時(shí)成為了***的入門編程語言工具。到后來,微軟推出Visual Basic實(shí)際上是為了和Borland(現(xiàn)已被收購)的Delphi競爭入門級(jí)編程工具市場(在相當(dāng)長的一段時(shí)間內(nèi)VB都不是Delphi的對(duì)手,可以參見本人的另一片隨筆《Borland和Microsoft的對(duì)話》,這直接導(dǎo)致了C#的誕生——C#——一種C++、Java、Object Pascal雜交的到的混血兒),憑借自己在BASIC用戶上的積累,在RAD領(lǐng)域混得不錯(cuò)了,微軟又趁熱打鐵的推出了VBS/VBE、VBA等等腳本語言,目的就是拉攏自己的VB用戶,使這種糟糕的語言能夠勉勉強(qiáng)強(qiáng)適應(yīng)系統(tǒng)GUI編程、辦公套件編程、數(shù)據(jù)庫編程,好了現(xiàn)在形成了一個(gè)有機(jī)的整體。一個(gè)程序員要么學(xué)多種語言來完成不同的任務(wù),要么學(xué)一種不夠好但夠用的語言——然后,一招鮮,吃遍天……學(xué)習(xí)一種語言的成本是很高的(要時(shí)間和電費(fèi)),所以有很多程序員會(huì)選擇微軟指定的這一標(biāo)準(zhǔn)。還有近幾年大紅的Object-C、Swift、Go,雖然名義上是開源的,但是誰知道他們的真正目的?除此之外,還有很多DSL(Domain-Specific Language,專業(yè)領(lǐng)域語言),比如sed和awk是為了處理文本,PHP是為了處理Web開發(fā)、Emacs Lisp和Vim腳本是為了擴(kuò)展編輯器功能,PostScript是為了排版,batch和各種shell script是為了shell編程等等。這里介紹一個(gè)典型:Adobe的ActionScript,它的作用就是為了支持Adobe自己的Flash,主要用于Flash動(dòng)畫和應(yīng)用程序,不論ActionScript語言自身發(fā)展的多好不過是一個(gè)擴(kuò)展罷了。
好 了,已經(jīng)介紹完了實(shí)用目的、學(xué)術(shù)目的、商業(yè)及特殊需要,相信各位對(duì)“為什么會(huì)有這么多種程序設(shè)計(jì)語言”這個(gè)問題有了更深刻的理解,也可能有了更多的疑惑。 如果你有任何疑惑或者愿意和我交流,歡迎留言。對(duì)了,除了我說的三個(gè)目的之外還有沒有別的創(chuàng)造新語言的原因?有,我自己設(shè)計(jì)了一種名為Grove的語言,用“樹”來完成過程編程和lambda表達(dá)式,改天把解釋器的源碼發(fā)出來交流一下。我的目的呢?Just for fun…
不要想你能為世界做什么,想想你該為世界做什么!