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