編程語言會發展到放棄基本數據類型之一的整數這一步嗎?我這樣問并不是真的要你嚴肅思考這個問題,更多的是希望打開你對未來的思路。我只是提出一種假想的情況:如果一股不可抗拒的力量遇到了一個不可移動的物體,會發生什么事。具體就本文而言:一種效率低得不可想象的語言遇到了性能強大得不可想象的硬件,會發生什么事。我看不出放棄整數類型有什么不妥。未來相當漫長。如果我們想要減少語言內核中基本公理的數目,不妨把眼光放得遠一點,想一想如果時間變量 t趨向無限會怎么樣。一百年是一個很好的參考指標,如果你覺得某個想法在一百年后仍然可能是難以令人接受,那么也許一千年后它也依然難以令人接受。
讓我說清楚,我的意思不是說所有的整數運算都用列表來實現,而是說語言的內核(不涉及任何編譯器的實現)可以這樣定義。在現實中,任何進行數學運算的程序可能都是以二進制形式表示數字,但是這屬于編譯器的優化,而不屬于語言內核語義的一部分。
另一種消耗硬件性能的方法就是,在應用軟件與硬件之間設置很多的軟件層。這也是我們已經看到的一種趨勢,許多新興的語言就被編譯成字節碼 。比爾•伍茲曾經對我說,根據經驗判斷,每增加一個解釋層,軟件的運行速度就會慢一個數量級。但是,多余的軟件層可以讓編程靈活起來。
Arc語言 最初的版本就是一個極端的例子,它的層很多,運行速度非常慢,但是確實帶來了相應的好處。 Arc是一個典型的“元循環”( metacircular)解釋器,在 Common Lisp的基礎上開發,很像約翰•麥卡錫在他經典的 Lisp論文中定義的 eval函數。 Arc解釋器一共只有幾百行代碼,所以很便于理解和修改。我們采用的 Common Lisp版本是 CLisp,它本身是在另一個字節碼解釋器的基礎上開發的。所以,我們一共有兩層解釋器,最上面那層效率低下得驚人,但是語言本身是能用的。我承認只是勉強可用,但是確實能用。
即使是應用程序,使用多層形式開發也是一種很強大的技巧。自下而上的編程方法意味著要把軟件分成好幾層,每一層都可以充當它上面那一層的開發語言。這種方法往往會產生更小、更靈活的程序。它也是通往軟件圣杯——可重用性( reusability)——的最佳路線。從定義上看,語言就是可以重用的。在編程語言的幫助下,你的應用程序越是采用這種多層形式開發,它的可重用性就越好。
可重用性這個概念多多少少與 20世紀 80年代興起的面向對象編程有些關聯。不管怎樣尋找證據,也不可能把這兩件事完全分開。某些使用面向對象編程開發出來的軟件確實具有可重用性,但是這不是因為它使用了面向對象編程,而是因為它的開發方法是自下而上的。以函數庫為例,它們具有可重用性,是因為它們屬于語言的一部分,而不是因為它們采用面向對象或者其他編程方法。
順便說一句,我不認為面向對象編程將來會消亡。我覺得,除了某些特定的領域,這種編程方法其實沒有為優秀程序員帶來很多好處,但是它對大公司有不可抗拒的吸引力。面向對象編程使得你有辦法對一團亂碼似的代碼進行可持續性開發。通過不斷地打補丁,它讓你將軟件一步步做大。大公司總是傾向于采用這樣的方式開發軟件。我預計一百年后也是如此。
既然是談論未來,最好談談并行計算( parallel computation),因為看上去并行計算好像就是為未來而存在的。無論怎么想,并行計算似乎都是未來生活的一部分。
它會在未來實現嗎?過去二十年,人們都在說并行計算馬上就會來臨。但是,到目前為止,它對編程實踐并沒有太大影響。這是真的嗎?芯片設計師已經不得不把它考慮在內,為多 CPU計算機開發系統軟件的程序員也是如此。
但是,真正的問題在于,并行計算到底能達到哪個抽象層次?一百年后它就會影響到開發應用軟件的程序員嗎?或者,它還只是編譯器作者需要考慮的事情,在應用軟件的代碼中根本就無處尋覓?
一種可能是,大多數可以用到并行計算的場合,人們都會放棄使用并行計算。雖然我總的預測是未來的軟件會揮霍掉大部分新增的硬件性能,但是并行計算是一個特例。我估計隨著硬件性能得到驚人的提升,如果你明確地說想要并行計算,那么肯定可以得到它,但是通常情況下你不會用到它。這意味著,除了一些特殊的應用程序,一百年后的并行計算不會是那種大規模的并行計算( massive parallelism)。我預料,對于普通程序員來說,一切更像對進程進行分叉,然后讓多個進程在后臺并行運行。
這是編程進行到很后期才要做的事情,屬于對程序的優化,類似于你想開發一種特定的數據結構來取代現有的數據結構。程序的第一個版本通常會忽略并行計算提供的各種好處,就好像編程開始時會忽略某種特定的數據結構給你帶來的好處一樣。
除了某些特定的應用軟件,一百年后,并行計算不會很流行。如果應用軟件真的大量使用并行計算,這就屬于過早優化了。
一百年后會有多少種編程語言?從最近來看,出現了大量的新語言。硬件性能提高是一個原因,這就允許程序員根據使用目的在運行速度和編程便利性之間做出不同的取舍。如果這就是未來的趨勢,那么一百年后強大的硬件只會使得語言數目變得更多。
但是,另一方面,一百年后的常用語言可能只有很少幾種。部分原因是基于我的樂觀主義,我相信在未來,如果你的作品確實很出色,你可能選擇的是一種開發起來很方便的語言。使用這種語言寫出來的軟件第一版的運行速度很慢,只有對編譯器進行優化設置后運行速度才會提升。既然我抱有這種樂觀主義,那么我還要做一個預言。有些語言可以達到機器的最高效率,另一些語言的效率則慢到剛剛可以運行而已,兩者之間存在巨大的差距。我預言一百年后,這段差距之間的各個點上都會有對應的編程語言存在。
因為這段差距正在變得越來越大,所以性能分析器( profiler)將變得越來越重要。目前,性能分析并沒有受到重視。許多人好像仍然相信,程序運行速度提升的關鍵在于開發出能夠生成更快速代碼的編譯器。代碼效率與機器性能的差距正在不斷加大,我們將會越來越清楚地看到,應用軟件運行速度提升的關鍵在于有一個好的性能分析器幫助指導程序開發。
我說將來可能只有很少幾種常用語言,但沒有把用于特定領域的“小眾語言”( little language)算進去。我覺得,這些嵌入式語言的想法很不錯,一定會蓬勃發展。但是我判斷這些“小眾語言”會被設計成相當薄的一層,使得用戶可以一眼看出在底下作為基礎的通用型語言,這樣就減少了學習時間,降低了使用成本。
誰來設計這些未來的語言?過去 10年最激動人心的趨勢之一就是開源語言的崛起,比如 Perl、 Python和 Ruby。語言設計已經被黑客接管。到目前為止這樣到底是好是壞還看不清楚,但是發展勢頭令人鼓舞。比如, Perl就有一些絕妙的創新。不過,它也包含了一些很糟糕的想法。對于一種充滿進取心、大膽探索的語言來說,這也是很正常的事。以它現在這種變化的速率,大概只有上帝才知道一百年后 Perl會變成什么樣。
有一句俗話說,如果你自己做不到,那就去當老師。這在語言設計領域不成立,我認識的一些最出色的黑客就在當教授。但是,當老師的人確實有很多事情不能做。研究性職位給黑客帶來了一些限制。在任何學術領域,都有一些題目是可以做的,另一些題目是不可以做的。不幸的是,這兩類題目的區別通常取決于它們寫成論文后看上去是不是很高深,而不是取決于它們對軟件業的發展是否重要。最極端的例子可能就是文學,文學研究者的任何成果幾乎對文學創作者都毫無影響。
雖然科學領域的狀況要稍好一點,但是研究者可以做的題目與能夠對設計優秀語言有所幫助的題目之間的交集小得令人沮喪。(奧林• 希弗斯曾經對這一點表達不滿,而且說得頭頭是道。)比如,研究變量類型的論文好像多得無窮無盡,盡管事實上靜態類型語言看來無法真正支持宏(在我看來,一種語言不支持宏,那就不值得使用了)。
新語言更多地以開源項目的形式出現,而不是以研究性項目的形式出現。這是語言的一種發展趨勢。另一種發展趨勢是,新語言的設計者更多的是本身就需要使用它們的應用軟件作者,而不是編譯器作者。這似乎是好的趨勢,我期待它繼續保持下去。
一百年后的物理學基本上不可能預測。但是計算機語言不一樣,現在就動手設計一種一百年后可以吸引使用者的新語言,這在理論上似乎是可能的。
設計新語言的方法之一就是直接寫下你想寫的程序,不管編譯器是否存在,也不管有沒有支持它的硬件。這就是假設存在無限的資源供你支配。不管是今天還是一百年后,這樣的假設好像都是有道理的。
你應該寫什么程序?隨便什么,只要能讓你最省力地寫出來就行。但是要注意,這必須是在你的思維沒有被當前使用的編程語言影響的情況下。這種影響無處不在,必須很努力才能克服。你也許覺得,對于人類這樣懶惰的生物,喜歡用最省力的方式寫程序是再自然不過的事情。但是事實上,我們的思想可能往往會受限于某種現存的語言,只采用在這種語言看來更簡單的形式,它對我們思想的束縛作用會大得令人震驚。新語言必須靠你自己去發現,不能依靠那些讓你自然而然就沉下去的思維定勢。
采用程序的長度作為它耗費工作量的近似指標是個很有用的技巧。這里的程序長度當然不是指字符的數量,而是指各種句法元素的總長度,基本上就是整個解析樹的大小。也許不能說最短的程序就是寫起來最省力的程序,但是當你一心想把程序寫得簡潔而不是松松垮垮時,你就更接近省力這個目標,你的日子也會變得好過得多。所以,設計語言的正確做法就變成了,看著一段程序,然后問自己是不是能把它寫得更短一點?
實際上,用想象出來的一種一百年后的語言來寫程序,這件事情的可靠程度,取決于你對語言內核的估計是否足夠正確。常規的排序,你現在就可以寫出來。但是,想要預測一百年后的語言使用什么函數庫就很難了。很可能許多函數庫針對的領域現在還根本不存在。比如,如果 SETI@home 計劃成功,我們就需要與外星人聯系的函數庫了。當然,如果外星人的文明高度發達,已經到了用 XML格式交換信息的地步,那就不需要新的函數庫了。
另一個極端是,我覺得今天你就能設計出一百年后的語言內核。事實上,在有些人看來,大部分語言內核在 1958年就已經設計出來了。
如果今天就能使用一百年后的編程語言,我們會用它編程嗎?觀古而知今。如果 1960年就能使用今天的編程語言,那時的人們會用它們嗎?
在某些方面,回答是否定的。今天的編程語言依賴的硬件在 1960年并不存在。比如, Python這樣的語言,正確的縮進( indentation)在編寫時很重要,但是 1960年的計算機沒有顯示器,只有打印機終端,所以編寫起來就不會很順利。但是,如果把這些因素排除在外(你可以假設,我們只在紙上編程), 20世紀 60年代的程序員會喜歡用現在的語言編程嗎?
我想他們會的。某些缺乏想象力、深受早期編程語言思想影響的人可能會覺得不可能。(沒有指針運算,如何復制數據?沒有 goto語句,如何實現流程圖?)但是我想,那時最聰明的程序員一定能輕松地使用今天的大多數語言,假定他們能得到的話。
如果我們現在就能擁有一百年后的編程語言,那就至少能用來寫出優秀的偽碼 。我們會用它開發軟件嗎?因為一百年后的編程語言需要為某些應用程序生成快速代碼,所以很可能它生成的代碼能夠在我們的硬件上運行,速度也還可以接受。相比一百年后的用戶,我們也許不得不對這種語言做更多的優化,但是總的來看,它應該仍然會為我們帶來凈收益。
現在,我們的兩個觀點就是:( 1)一百年后的編程語言在理論上今天就能設計出來;( 2)如果今天真能設計出這樣一種語言,很可能現在就適合編程,并且能夠產生更好的結果。如果我們把這兩個觀點聯系起來,那就得出了一些有趣的可能性。為什么不現在就動手嘗試寫出一百年后的編程語言呢?
當你設計語言的時候,心里牢牢記住這個目標是有好處的。學習開車的時候,一個需要記住的原則就是要把車開直,不是通過將車身對齊畫在地上的分隔線,而是通過瞄準遠處的某個點。即使你的目標只在幾米開外,這樣做也是正確的。我認為,設計編程語言時,我們也應該這樣做。
文章來源于領測軟件測試網 http://www.kjueaiud.com/