很難預測一百年后的人類生活,只有少數幾件事是可以確定的。那時,汽車將具備低空飛行能力,城市規劃的法規將放寬,大樓可以造到幾百層,大街上一天到晚看不見太陽,女性個個都學過防身術。本文只想討論其中的一個細節:一百年后,人們使用什么語言開發軟件?
為什么這個問題值得思考?原因不是我們最終會用上這些語言,而是幸運的話,我們從現在開始就能用上這些語言。
我認為,編程語言就像生物物種一樣,存在一個進化的脈絡,許許多多分支最終都會成為進化的死胡同。這種現象已經發生了。 Cobol語言曾經流行一時,但是現在看來沒有任何后續語言繼承它的思想。它就像尼安德特人 一樣,進化之路已經走到了盡頭。
我預言 Java也會如此。有人寫信說:“你怎么能說 Java不會成功呢?它已經成功了!蔽矣X得這要看你的成功標準是什么。如果標準是相關書籍的出版量,或者是相信學會 Java就能找到工作的大學生數量,那么 Java確實已經成功了。當我說 Java不會成功時,我的意思是它和 Cobol一樣,進化之路已經走到了盡頭。
這只是我的猜測,未必正確。這里的重點不是看衰 Java,而是提出編程語言存在一個進化的脈絡,從而引導讀者思考,在整個進化過程中,某一種語言的位置到底在哪里?之所以要問這個問題,不是為了一百年后讓后人感嘆我們曾經如此英明,而是為了找到進化的主干。它會啟發我們去選擇那些靠近主干的語言,這樣對當前的編程最有利。
無論何時,選擇進化的主干可能都是最佳方案。要是你不幸選錯了,變成了一個尼安德特人,那就太糟了。你的對手克魯馬努人時不時就會來攻打你,把你的食物全部偷走。
這就是我想找出一百年后的編程語言的原因。我不愿意押錯賭注。
編程語言的進化與生物學進化還是有區別的,因為不同分支的語言會發生聚合。比如, Fortran分支看來正在與 Algol 的繼承者聚合。理論上,不同的生物物種也可能發生聚合,但是可能性很低,所以大概從來沒有真正出現過。
編程語言之所以可能出現聚合,一個原因是它的概率空間 比較小,另一個原因是它的突變不是隨機的。語言的設計者們總是有意識地借鑒其他語言的設計思想。
對于語言設計者來說,認清編程語言的進化路徑特別有用,因為這樣就可以照著樣子設計語言了。這時,認清進化的主干就不僅有助于識別現存的優秀語言,還可以把它當作設計語言的指南。
任何一種編程語言都可以分成兩大組成部分:基本運算符的集合(扮演公理的角色)以及除運算符以外的其他部分(原則上,這個部分可以用基本運算符表達出來)。
我認為,基本運算符是一種語言能否長期存在的最重要因素。其他因素都不是決定性的。這有點像買房子的時候你應該先考慮地理位置。別的地方將來出問題都有辦法彌補,但是地理位置是沒法變的。
慎重選擇公理還不夠,還必須控制它的規模。數學家總是覺得公理越少越好,我覺得他們說到了點子上。
你仔細審視一種語言的內核,考慮哪些部分可以被摒棄,這至少也是一種很有用的訓練。在長期的職業生涯中,我發現冗余的代碼會導致更多冗余的代碼,不僅軟件如此,而且像我這樣性格懶散的人,我發現在床底下和房間的角落里這個命題也成立,一件垃圾會產生更多的垃圾。
我的判斷是,那些內核最小、最干凈的編程語言才會存在于進化的主干上。一種語言的內核設計得越小、越干凈,它的生命力就越頑強。
當然,猜測一百年后人們使用什么編程語言,這本身就是一個很大的假設。也許一百年后人類已經不編程了,或者直接告訴計算機想做什么,計算機就會自動完成。
不過,到目前為止,計算機智能并沒有取得太大進展。我猜測一百年后,人們還是使用與現在差不多的程序指揮計算機?赡苡幸恍┪覀兘裉煨枰幊探鉀Q的問題,那時已經不需要編程了,但是我想,那時還會存在大量與今天一樣的編程任務。
你可能認為只有那些自以為是的人才會去預言一百年后的技術。但是,請不要忘記,軟件發展的歷史已經走過了 50年。在這 50年中,編程語言的進化其實是非常緩慢的,因此展望一百年后的語言并不是虛無縹緲的想法。
編程語言進化緩慢的原因在于它們并不是真正的技術。語言只是一種書寫法,而程序則是一種嚴格符合規則的描述,以書面形式記錄計算機應該如何解決你的問題。所以,編程語言的進化速度更像數學符號的進化速度,而不像真正的技術(比如交通或通信技術)的進化速度。數學符號的進化是緩慢的漸變式變化,而不是真正技術的那種跳躍式發展。
無論一百年后的計算機是什么樣子,我們基本上可以斷定它們的運行速度一定會快得多。如果摩爾定律依然成立,一百年后計算機的運行速度將是現在的 74乘以 10的 18次方倍(準確地說是 73 786 976 294 838 206 464倍)。真是讓人難以想象。不過實際上更現實的預測并不是速度會提高這么多,而是摩爾定律最終將不成立。不管是什么東西,如果每 18個月就增長一倍,那么最后很可能會達到極限。但那時的計算機比現在快得多大概是毫無疑問的。即使最后只是略微快了 100萬倍,也將實質性地改變編程的基本規則。如果其他條件不變,現在被認為運行速度慢的語言(即運行的效率不高)將來會有更大的發展空間。
那時,依然會有對運行速度要求很高的應用程序。我們希望計算機解決的有些問題其實是計算機本身引起的。比如,計算機處理視頻的速度取決于生成這些視頻的另一臺計算機。此外,還有一些問題本身就要求無限快的處理能力,比如圖像渲染、加密 /解密、模擬運算等。
既然在現實中一些應用程序本身的效率較低,而另一些應用程序會耗盡硬件提供的所有運算能力,那么有了更快速的計算機就意味著編程語言不得不應付更多的極端情況,涵蓋更大范圍的效率要求。我們已經看到這種情況發生了。要是以幾十年前的標準衡量,有一些使用新語言開發的熱門應用程序對硬件資源的浪費非常驚人。
不僅編程語言有這種現象,這實際上是一種普遍的歷史趨勢。隨著技術的發展,每一代人都在做上一代人覺得很浪費的事情。 30年前的人要是看到我們今天如此隨意地使用長途電話,一定會感到震驚。 100年前的人要是看到一個普通的包裹竟然也能享受一天內從波士頓發件、途經孟菲斯、抵達紐約的待遇,恐怕就要更震驚了。
我已經預測了,一旦未來硬件的性能大幅提高將會發生什么事。新增加的運算能力都會被糟蹋掉。
在我學習編程的年代,計算機還是稀罕玩意。我記得當時使用的微機型號是 TRS-80,它的內存只有 4K,為了把 BASIC程序裝入內存,我不得不把源碼中的空格全部刪除。我一想到那些極其低效率的軟件,不斷重復某些愚蠢的運算,把硬件的計算能力全部占用,就感到無法忍受。但是,我的這種反應是錯的,我就像某個出身貧寒的窮孩子,一聽到要花錢就舍不得,即使把錢用在重要場合(比如去醫院看病)都覺得很難接受。
某些浪費確實令人厭惡。比如有人就很討厭 SUV(運動型多用途車),即使它采用可再生的清潔能源也改變不了看法,因為 SUV來自一個令人厭惡的想法(如何使得小貨車看上去更有男子漢氣概)。但是,并非所有的浪費都是壞的。既然如今的電信基礎設施已經如此發達,再掐著時間打長途電話就有點錙銖必較了。如果有足夠的資源,你可以將長途電話和本地電話視為同一件事,一切會變得更輕松。
浪費可以分成好的浪費和壞的浪費。我感興趣的是好的浪費,即用更多的錢得到更簡單的設計。所以,問題就變成了如何才能充分利用新硬件更強大的性能最有利地“浪費”它們?
對速度的追求是人類內心深處根深蒂固的欲望。當你看著計算機這個小玩意,就會不由自主地希望程序運行得越快越好,真的要下一番功夫才能把這種欲望克制住。設計編程語言的時候,我們應該有意識地問自己,什么時候可以放棄一些性能,換來一點點便利性的提高。
很多數據結構存在的原因都與計算機的速度有關。比如,今天的許多語言都同時有字符串和列表。從語義上看,字符串或多或少可以理解成列表的一個子集,其中的每一個元素都是字符。那么,為什么還需要把字符串單列為一種數據類型呢?完全可以不這么做。只是為了提高效率,所以字符串才會存在。但是,這種以加快運行速度為目的、卻使得編程語言的語義大大復雜的行為,很不可取。編程語言設置字符串似乎就是一個過早優化的例子。
如果我們把一種語言的內核設想為一些基本公理的集合,那么僅僅為了提高效率就往內核添加多余的公理,卻沒有帶來表達能力的提升,這肯定是一件很糟的事。沒錯,效率是很重要,但是我認為修改語言設計并不是提高效率的正確方法。
正確做法應該是將語言的語義與語言的實現予以分離。在語義上不需要同時存在列表和字符串,單單列表就夠了。而在實現上做好編譯器優化,使它在必要時把字符串作為連續字節的形式處理。
對于大多數程序,速度不是最關鍵的因素,所以你通常不需要費心考慮這種硬件層面上的微觀管理。隨著計算機速度越來越快,這一點已經越發明顯了。
語言設計時,對實現方式少作限制還會使得程序具備更大的靈活性。語言的規格發生變化不僅是無法避免的,也是合理的。通過編譯器的處理,按照以前規格開發的軟件就會照常運行,這就提供了靈活性。
essay(論文)這個詞來自法語的動詞 essayer,意思是“試試看”。從這個原始意義來說,論文就是你寫一篇文章,試著搞清楚某件事。軟件也是如此。我覺得一些最好的軟件就像論文一樣,也就是說,當作者真正開始動手寫這些軟件的時候,他們其實不知道最后會寫出什么結果。
Lisp語言的黑客早就明白數據結構靈活性的價值。我們寫程序的第一版時,往往會把所有事情都用列表的形式處理。所以,這些最初版本可能效率低下得驚人,你必須努力克制自己才能忍住不動手優化它們,這就好像吃牛排的時候必須努力克制自己才能不去想牛排是從哪里來的一樣,至少對我來說是這樣的。
一百年后的程序員最需要的編程語言就是可以讓你毫不費力地寫出程序第一版的編程語言,哪怕它的效率低下得驚人(至少按我們今天的眼光來看是如此)。他們會說,他們想要的就是很容易上手的編程語言。
效率低下的軟件并不等于很爛的軟件。一種讓程序員做無用功的語言才真正稱得上很爛。浪費程序員的時間而不是浪費機器的時間才是真正的無效率。隨著計算機速度越來越快,這會變得越來越明顯。
我覺得,放棄字符串類型已經是大家可以接受的想法了。 Arc語言已經這樣做了,看上去效果不錯。以前用正則表達式很難描述的一些操作,現在用回歸函數可以表達得很簡單。
這種數據結構的扁平化趨勢會怎么發展?我極其努力地設想各種可能,得到的結果甚至令我自己都嚇了一跳。比如,數組會不會消失?畢竟數組只是散列表的一個子集,其特點就是數組的鍵全部都是整數向量。進一步說,散列表本身會不會被列表取代呢?
還有比這更驚人的預言。在邏輯上其實不需要對整數設置單獨的表示法,因為可以把它們也看作列表,整數 n可以用一個 n元素的列表表示。這一樣能完成數學運算,只是效率低得讓人無法忍受。
文章來源于領測軟件測試網 http://www.kjueaiud.com/