Scala創始人:創造比Java更好的語言
原創【51CTO快譯】近日,Scala語言的創始人Martin Odersky接受了Artima的一系列訪談。Martin Odersky在2001年開始創立Scala語言,最初的動機是因為對Java的一些特性感到不滿,想要創建一個比Java更高級的語言。他基本達到了這個目的:Scala成為了Java的首選替代之一。如果你對Scala語言還不太了解,可以參考Scala編程語言簡介。
本文是訪談的第一個系列。在這部分節選的內容中,Martin Odersky詳細的描述了他創建Scala的前因后果:他是如何創建這個基于JVM和Java類庫的、不同于Java的語言的。
Scala創始人Martin Odersky
因編譯器而著迷
Artima:讓我們從頭開始。您是如何開始介入編程語言的?
Martin Odersky:我最喜愛的科目一直都是編譯器和編程語言。1980年,當我在讀大學的時候,第一次接觸編譯器,我就馬上想自己建立一個編譯器。那時候我唯一可以買得起的電腦是Sinclair ZX 80,它只有1KB的RAM 。幸運的是,不久后我有了一個性能更強大的機器Osborne-1,它是世界上第一款“便攜式”(筆記本)電腦,看上去就像一個傾斜90度的縫紉機。它有一個5英寸的顯示屏,每行顯示52個字符。但它有一個56KB可用的RAM以及兩個90K的軟盤驅動器。
在那些日子里,我花了一些時間與我大學里的另一名學生Peter Sollich一起研究。我們一起了解了一種新語言Modula-2,我們發現它非常棒,而且設計良好。因此,我們計劃編寫一個適用于8位Z80計算機的Modula-2編譯器。但是出現了一個小問題,Osborne附帶的唯一語言是Microsoft Basic,這完全不適合我們的想法,因為它甚至不支持帶參數的程序,只能使用全局變量。而當時的其他編譯器對于我們來說又都太昂貴了。因此,我們決定采用經典的bootstrapping(引導)技術。Peter使用Z80匯編語言為一個小小的Pascal子集編寫了第一個編譯器。然后,我們不斷改進這個編譯器,使它能夠逐漸編譯稍微大量的語言。經過幾代版本后的改進,直到我們可以編譯所有的Modula-2語言。它可以產生解釋后的字節碼以及Z80二進制碼。該字節碼是當時所有系統中最簡潔的,其二進制版本是當時8位機上最快的。我們的這個編譯器在當時看來是能力相當不錯的系統。
我在我們即將要完成我們的編譯器之前,Borland帶著其Turbo Pascal橫空出世,同時正在考慮入主Modula-2市場。事實上,Borland決定購買我們的Modula-2編譯器,并將以Turbo Modula-2的名字出售,適用于CP/M芯片,并想要開發其IBM PC版本,我們提議為他們編寫IBM PC版本,但他們告訴我們,他們對于這個版本的開發已經做好了安排。但不幸的是,這個版本的開發周期遠遠超出了他們的計劃。3、4年后,其編碼實現小組從公司中獨立出來,并推出了TopSpeed Modula-2。在沒有IBM PC版本時,Borland繼Turbo-Modula-2之后就再也沒有任何市場競爭力了。
(51CTO編者:這個曾經的開發巨頭Borland于日前隕落。詳情可參考Borland傳奇終結 被英國軟件商7500萬美元收購)
當我們完成Modula-2編譯器時,Borland提議要雇用Peter和我。于是Peter去加入了他們的行列。我曾經也想這樣做,但有個問題是,我仍然還有一年的課程沒有讀完,而且還要計劃讀碩士。當時我很受誘惑,甚至想過退學。但最后,我決定堅持讀完大學。之后,在做碩士項目期間(有關增量分析的課題),我發現我更喜歡做研究。于是最終我放棄了加入Borland編寫編譯器的想法,而是繼續在蘇黎世ETH攻讀Niklaus Wirth的博士,Niklaus Wirth是Pascal和Modula-2的發明者。
為了更好的Java而努力
Artima:Scala是如何出現的?Scala的發展史是什么樣的?
Martin Odersky:在我的蘇黎世生活快要結束的時候,大概是1988到1989年,我開始非常喜歡函數式程序設計。于是,我一直留在那里做研究,最終成為一名德國卡爾斯魯厄的大學教授。我最初的工作偏向于編程的理論方面,比如call-by-need lambda(惰性λ)演算。這項工作是同Phil Wadler共同進行的,他當時在格拉斯哥大學。有一天,Phil告訴我,他的研究組里一個很勤奮的助教聽說有一種新的語言要被推出,目前這種語言仍處于alpha版本階段,語言的名字為Java。這個助教告訴Phil:“看看這個Java,它所具有的靈活性。它擁有字節碼,它可以運行在網絡上,它具有垃圾收集功能。這個Java將要毀滅你們。你們準備怎么應對?” Phil說,是的,也許他說的有些道理。
對此的回應就是,Phil Wadler和我決定從函數式程序設計中提取出一些想法,并把這些想法轉移到Java空間。這一努力成就了一個新語言Pizza,它具有函數式程序設計的三個特點:泛型、高階函數以及模式匹配。Pizza最初發布于1996年,是在Java發布的一年之后。Pizza是比較成功的,因為它表明,我們可以在JVM平臺上實現函數式語言的特性。
然后,我們接觸了來自Sun核心開發團隊的Gilad Bracha和David Stoutamire。他們說:“我們對你們一直所研究的泛型非常感興趣,讓我們一起做一個關于泛型的項目吧。”那就是GJ(泛型Java)。因此,我們于1997/98年開發了GJ,6年后,對它進行一些補充,使之成為了Java 5中的泛型功能。特別是,補充了由Gilad Bracha和奧胡斯大學的人們一起獨立開發的Java泛型通配符。
雖然我們的泛型擴展被擱置了6年,但Sun公司對于我為GJ所開發的編譯器表現出了濃厚的興趣。經證明,我所寫的編譯器比他們的第一個Java編譯器更穩定、更易于維護。因此,他們決定從2000年推出的1.3版本開始,將GJ編譯器作為其標準的Javac編譯器。
#p#
然后,為了比Java更好的語言
Martin Odersky:現在,經過Pizza和GJ的經歷,我有時會感到沮喪,因為Java是一個具有非常強的約束的語言。因此,很多事情都不能像我想象的那種方式那樣去做——那種我原本確信是正確的方式。所以本來,本質上我的工作是集中于讓Java變得更好,但在那之后,我決定,現在是時候應該后退一步看看了。我想要從零開始,看看我能否可以設計出一些比Java更好的東西。但與此同時,我知道我不能從零開始。我需要借助一個現有的基礎架構,否則這只是不切實際地引導自己去無中生有,沒有任何類庫、工具等等。
所以我決定,即使我想要設計出一種不同于Java的語言,始終還是要借助Java的基礎架構——JVM和它的類庫。這就是我的想法。我認為在那個時候,這是一個很好的機會,那時候我正在洛桑聯邦理工大學擔任教授,這為我提供了一個極好的獨立研究的環境。我可以組建一個小型研究組。
開始的時候,我們非常激進。我們想要在一個現有的非常好的模型上創建一些東西,該模型為join calculus(連接演算)。我們創建了一個連接演算的面向對象版本Functional Nets,以及一種新語言Funnel。但是,又過了一段時間,我們發現,Funnel是一個非常純粹的語言,并不一定很實用。Funnel是建立在一個非常小的內核之上。很多人們通常認為理所當然的事情(如類,或模式匹配)都只能通過編碼到內核才能實現。從學術的角度來看這是一項非常優雅的技術。但運用于實際它就并不那么好。初學者覺得這種必要的編碼相當困難,而高手們卻覺得不得不一次又一次地編碼非常無聊。
因此,我們決定再次從頭開始,并做一些介于Funnel(非常純粹的學術語言)和GJ(非常實用但卻存在一些限制的語言)中間的技術。我們希望創造一些能夠實用和有價值,同時又比Java高級的東西。在大約2002年時,我們開始著手進行這種語言,稱之為Scala。首次公開發布是在2003年。相對比較大規模的一次重新設計是在2006年初。從此,它開始穩步成長。
更好的Java受到的約束
Artima:您說您那時候感到很沮喪,遇到一些約束,需要向后兼容Java。您能否提供一些遇到約束的具體的例子?
Martin Odersky:在泛型設計中,有很多非常強硬的約束。其中最強、最難以應付的是,它必須充分地向后兼容非泛型Java。Collections類庫只停留在1.2版本,而且僅僅因為泛型的出現,Sun不準備推出全新的Collections類庫。因此,只能完全透明工作。(51CTO編者:有關Collections類庫的更多內容,可參考這篇基于JDK 5.0一些collection類的使用總結,以及《Java語言的科學與藝術》一書中的Collection層次結構章節。)
這就是為什么總會存在一些相當難看的東西。你總是不得不使用具有泛型類型的非泛型類型,即所謂的raw(原始)類型。還有,你不能改變數列行為,否則就會有未經檢查的警告。最重要的是,你不能利用數組做你想做的很多事情,比如生成一個具有類型參數的數組。后來在Scala,我們知道了實際上能如何實現這些事情,但是這可能僅僅是因為我們給Scala設置的條件是協變數組。
Artima:您能否就Java的協變數組詳細說明一下該問題?
Martin Odersky:當Java剛出現時,Bill Joy和James Gosling以及其他Java組成員都認為,Java應該有泛型,只是他們沒有足夠的時間做出詳細設計。所以由于Java中沒有泛型,至少最初階段沒有,他們就認為,數組不得不是協變的。例如,這意味著一個字符串(String)數組是一個對象(Object)數組的子類型。其原因是他們希望能夠重寫,比如,一個“通用”排序方法,采用了一個對象數組和一個用來排序該數組的比較器,然后讓你傳送一個字符串數組的參數給它。通常情況下這屬于類型不健全。這就是為什么在Java中你會獲得一個數組存儲例外。這實際上也證明,這種同樣的事情引起了對于數組泛型實現的需求。這就是為什么在Java中泛型并不好使。你不能定義一個字符串的列表數組,這是不可能的。你只能被迫使用難看的原始類型,永遠都只能是一個列表數組。因此,這有點類似原罪。他們對此做出了非常迅速的回應,認為這是一個快速破解。但隨后實際上每一個設計決定都被毀滅了。因此,為了不陷入同樣的陷阱,我們不得不中斷,并提出現在我們將不向上兼容Java,我們也想做一些不同的事情。
編者后記
Scala到目前為止還是一個相對小眾的語言,在TIOBE每月的排行榜上都在20到30之間浮動,與每月排名第一的Java在流行程度上仍有很大的差距。然而Scala在數年之間已經得到了越來越多開發者的關注,在國外的開發者討論區中常常會看到有Scala的專區。Scala在現在以及未來的開發界絕對是一個不可忽視的語言。
【相關閱讀】