Scala這門語言最早是如何被設計出來的?
Scala起源
Martin Odersky訪談(第一部分)by Bill Venners and Frank Sommers
譯者楊博
摘要
Martin Odersky與Bill Venners談論Scala編程語言如何創立的相關歷史。Scala,一門通用用途、面向對象、函數式的JVM語言,是瑞士洛桑聯邦理工大學教授Martin Odersky的心血結晶。本訪談系列由多部分組成。本文是第一部分,Martin Odersky與Artima網站的Bill Venners談論了Scala的歷史。
發現編譯器的魅力
Bill Venners: 我們從頭開始談談吧。你最早是如何開始涉獵編程語言的呢?
Martin Odersky: 編譯器和編程語言一直都是我最喜歡的主題。我第一次鑽研編譯器是在1980年。那時我還是個本科生,想編寫一個自己的編譯器。 當時我唯一能遠程用上的電腦是Sinclair ZX 80。它上面有1KB內存。我差點就在上面開始嘗試了。但幸好我很快就得到更強大的機器Osborne-1。這是世界上第一款「攜帶型」計算機,遠看就像一台傾斜90度的縫紉機。 它的屏幕五英寸大,每行只能顯示52個小小的字元。但它亦有驚人之處。內存多達56KB,軟盤驅動器有兩個,每個容量90KB。
那些日子,我花了一些時間與另一個叫做Peter Sollich的同學呆在一起。我們學了一門新語言Modula-2。我們覺得它既優雅又精緻。 於是我們誕生出了一個新計劃:我們要為8位計算機Z80編寫Modula-2編譯器。編寫時有個小問題,Osborene附帶的唯一語言是微軟的Basic語言。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版,但他們告訴我們,他們另有計劃。 不幸的是,他們開發IBM PC版所費時間遠超預期。 產品發布已經是三四年後。實現團隊已經從公司分拆,成為了我們所知的TopSpeed Modula-2。由於缺了IBM PC版,Borland公司從未為Turbo-Modula-2提供營銷資源, 所以它一直沒什麼名氣。
我們完成Modula-2編譯器之際,Borland公司立時就邀請我和Peter加入。Peter去了他們公司。我差點也去了。但我的問題是,我還有一年課程要讀,還有碩士項目要做。那時我差點沒忍住輟學的誘惑。 最後,我決定堅持上大學。 在我碩士項目期間(關於增量解析),我發現我挺喜歡科研的。所以最後,我放棄加入Borland編寫編譯器,轉而攻讀博士學位。我的導師是Pascal和Modula-2的發明者,蘇黎世聯邦理工學院的Niklaus Wirth。
改善Java的工作
Bill Venners: Scala是怎麼誕生的?有什麼歷史嗎?
Martin Odersky: 在我快要離開蘇黎世時,大約1988年至1989年,我越來越喜歡函數式編程了。所以我繼續科研之路,並最終成為德國卡爾斯魯厄大學教授。 我最初工作更偏向編程的理論方面,比如call-by-need lambda演算. 這項工作與Phil Wadler共同完成。當時他在格拉斯哥大學。 有一天,Phil告訴我,他的組裡有個熱血助理聽說一門新的語言剛出來,仍處於Alpha階段,名叫Java。 助理向Phil宣告:「瞧瞧我大Java,它有移植性,有位元組碼,能運行在Web上,還有垃圾收集。這東西可以完爆你。你打算怎麼辦呢?」Phil說:「呃,可能他說得有點道理。」
答案是,我和Phil Wadler決定從函數式編程中提取一些點子,移植到Java界。 我們的努力轉化成為一門名叫Pizza的語言,其中具備函數式編程的三大特性:泛型、高階函數和模式匹配。Pizza首次發佈於1996年,即Java推出後一年。Pizza還算成功,因為它表明,JVM平台上可以實現函數式語言特性。
接著,Sun核心開發團隊的Gilad Bracha和David Stoutamire聯繫了我們。他們說:「我們對你已經做的泛型什麼的東西還真挺感興趣。我們來做個新項目專註這個功能吧。」這個新項目就成了GJ(Generic Java)。 因此,我們在1997/1998年開發了GJ。6年後,GJ再加上當時我們還沒做的額外功能,就成為了Java 5中的泛型。那個沒做的額外功能就是Java泛型的通配符功能,後來由Gilad Bracha和奧胡斯大學的人獨立開發。
雖然我們的泛型擴展被擱置了6年,但Sun對我為GJ寫的編譯器產生了強烈的興趣。有證據表明,GJ比他們的第一個Java編譯器更穩定,更易於維護。 因此,他們決定,在2000年發布的Java 1.3版及以後版本的中,都採用GJ編譯器作為標準javac編譯器。
設計比Java更好的語言
Martin Odersky: 此刻,在Pizza和GJ的經驗中,我常常感到沮喪,因為Java是一門具有硬性約束的語言。因此,我做很多事情時都不能用我本來想用的方式,不能用我確信正確的方式來做。畢竟那時候我的工作重點是改善Java。所以,在那段時期過去以後,我決定,我該退一步了。我想從一張白紙開始,看看我能不能設計出比Java更好的東西。但同時我又知道我不能完全從頭開始。 我必須利用上現有的基礎設施,不然的話,光是無中生有的自舉,沒有任何庫,工具之類的東西,根本就不現實。
所以我決定,即使我想設計不同於Java的語言,總歸得連接到Java的基礎設施——即JVM和Java庫。 我的想法就是這樣。 當時我正有個大好機會,因為當時我在洛桑聯邦理工學院做教授,這讓我有了獨立研究的良好環境。我可以組成一個小團體的研究人員,可以專心工作,不會因外部的贊助人而耗光我所有的時間。
起初我們相當激進。 我們想創造的東西,基於一種非常優美的並發模型,叫做join演算。我們創造了面向對象版的join演算,叫做Functional Nets,還創造了一門語言,叫做Funnel。過了一段時間,我們發現,Funnel語言的確非常純粹,但卻算不上很實用。 Funnel根植於非常小的內核。 人們認為理所當然應具備的功能(比如類、模式匹配)都必須要對內核編碼才能提供。從學術角度看,這技術非常優雅。但實踐中不大行得通。 初學者想要找出該怎麼編碼會相當困難,而專家卻發現一次又一次重複編碼又很無聊。
結果,我們決定再次重頭做點事情,介於純粹的學術語言Funnel,以及非常務實但受限重重的GJ之間。我們要創造的東西,將會既具有實用價值,又比Java中的先進。2002年時,我們開始開發這門新的語言。我們叫它Scala。首次公開發佈於2003年。 2006年年初時有一次相對較大的重新設計。 此後它一直持續成長並逐漸穩定。
改善Java時所受的約束
Bill Venners: 你說,你需要與Java向後兼容,你受到重重約束,因而多次讓你感到沮喪。你能否具體舉些例子說說,有哪些事,戴著鐐銬跳舞時無法做到,而只保證二進位兼容但無視源代碼兼容時就可以做到?
Martin Odersky: 設計泛型時,我遇到許多非常非常緊的約束。最緊的約束,最難應付的,就是被迫要完全向後兼容無泛型Java。這個故事是這樣的,Java1.2才剛剛加入集合庫,Sun不想僅僅因為推出了泛型就另外新增一整套集合庫。而不這麼做,泛型就得以完全透明的方式實現。
這就是存在一些相當醜陋的東西的原因。 你不得不處處讓無泛型類型和泛型類型一起工作,即所謂的raw類型。而且你還不能改變數組的行為不然就會碰上unchecked警告。最重要的是,處理數組時無法按你想要的方式來做,比如創建具有類型參數T的數組,或者創建你還不知道元素類型的數組。反正你就是沒辦法做。後來我們在Scala中確實找到了辦法,但前提條件是我們讓Scala的數組不再支持協變和逆變。
Bill Venners: 你能否闡述一下Java的協變數組有些什麼問題嗎?
Martin Odersky: Java發布初版時,Bill Joy、James Gosling以及Java團隊的其他成員都覺得Java就該支持泛型,可惜他們沒有時間好好設計。所以考慮到Java(至少初版)不支持泛型,他們覺得至少要讓數組能支持協變。這就意味著,舉例說吧,String數組就是Object數組的子類型。這麼做的原因是,他們想要支持編寫某種泛型排序方法,接受一個Object數組參數,以及一個比較器(comparator)參數,而該方法可以把Object數組排序。然後,允許你把String數組傳入其中。總而言之,這類設計算得上一般意義上的類型錯亂了。這就是你在Java中會遇到數組修改異常的罪魁禍首。實際上,也正是它導致泛型數組無法正常實現以及數組在Java泛型中根本沒法用的原因。你不能聲明字元串列表的數組,壓根就做不到。你必須用醜陋的raw類型,只能永無止盡地使用列表的數組。因此,它有點像原罪。 他們做得很快,覺得這只是權宜之計。它實際上把未來的每一次設計決定全都毀了。 因此,為了不再次陷入同樣的陷阱,我們不得不另尋他路。現在我們宣布,不會與Java向上兼容,有些事情,我們想要做得不同。
2003 年,一個叫 Martin Odersky 的醉漢看見了好時瑞森花生醬杯的廣告,展示了某個人的花生醬倒入另一個人的巧克力的場景,他忽然有了個點子,創造了 Scala,一種結合了面向對象和函數式編程的語言。這同時激怒了兩個陣營的忠實信徒,他們立刻宣布要發動聖戰燒死異教徒。
http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html
推薦閱讀: