計算機科學(xué)的道路上布滿了什么將成為“下一個大事件”這樣的軀殼。盡管許多的小生境語言確實在腳本或是特定應(yīng) 用中找到了一些用武之地,但C(及其衍生工具)和Java語言是難以被取代的。不過Red Hat的Ceylon似乎是一些語言功能的一個很有意思的組合,其使用了大家熟知的C風(fēng)格的語法,但是除了強調(diào)簡潔之外,其還提供面向?qū)ο蠛鸵恍┖苡杏玫?函數(shù)方面的支持。研究一下Ceylon,看看這一未來的VM語言是否能夠在企業(yè)級的軟件開發(fā)中找到自己的位置。
Linux和開源通常會與最前沿的語言設(shè)計之間存在著一定的關(guān)系,其可能是可用來支持語言開發(fā)的工具,或者是平臺的開放性促進了語言設(shè)計的進步?;蛘呖赡?是這樣的情況,基于開源技術(shù)的那些開放式語言(比如說GNU Compiler Collection系列、Ruby、Python和Perl)非常的優(yōu)秀,因為它們歡迎和鼓勵試驗使用(更不用提Red Hat就是Ceylon背后的公司)。無論是出于何種原因,Linux開發(fā)者可以使用大量的各種語言,從較少被用到已有了一定年頭的語言到最新最先進的產(chǎn) 品。
但在一個有著C/C++、Java™語言、Scala、Ruby、Python、Perl、Erlang、Lua、Scheme以及其他許多 語言的世界中,我們還有必要關(guān)心一種致力于面向業(yè)務(wù)的企業(yè)級軟件開發(fā)的新語言的宣告出現(xiàn)嗎?在許多情況下,回答是否定的。不過讓我們來研究一下Red Hat為未來提供的一種名為Ceylon的語言,看一看它是否能夠上升到當今最受歡迎語言的行列中來。
Ceylon并不是Java
”Ceylon不是Java,它是一種深受Java影響的新語言,是由一些Java愛好者設(shè)計出來的,他們不覺得有什么不對,Java并不會馬上過氣,所以不存在誰殺死它的問題。“——Gavin King
Ceylon的介紹
Ceylon是一個出自Red Hat的新項目,由Gavin King領(lǐng)導(dǎo)。King是Hibernate項目的創(chuàng)始人,該項目是一個Java語言內(nèi)部的持久化解決方案。盡管King是Java技術(shù)的愛好者——該技 術(shù)是首個適用于大規(guī)模開發(fā)的語言——但按照他的話來講,該語言有著一些令人受挫的地方(其中包括泛型一類的語言復(fù)雜性、設(shè)計輕率和晦澀的Standard Edition SDk、笨拙的注解語法、破碎的塊結(jié)構(gòu)、XML依賴性等等)。
因此,King提出了一個問題,在從Java語言和SDK的優(yōu)勢和劣勢中學(xué)到一些教訓(xùn)之后,語言應(yīng)該具備什么樣的形式才對?他的答案是 Ceylon,一種靜態(tài)類型語言,保留了Java語言的一些最好的功能特性(也運行在JVM上),但在語言的可讀性、內(nèi)置的模塊化以及諸如高階函數(shù)一類的 函數(shù)式語言特征的納入方面做了改進。Ceylon還采用了C和Smalltalk的一些特性,不過它更像Java語言,這一新語言專注在業(yè)務(wù)計算上,但它 也很靈活,可用在其他領(lǐng)域中。
有些人把Ceylon稱作“Java 殺手”(可能是因為Java語言的前途問題),但實際上Ceylon運行在JVM上,因此它是Java技術(shù)的一種延伸而不是替代。使用JVM來支持 Ceylon的執(zhí)行是一種理想的模式,因為這意味著Ceylon(像Java一樣)是可跨多種目前支持JVM的架構(gòu)移植的。
Ceylon的語言特性
當今大多數(shù)的語言都不再遵從某種簡單的分類,代以體現(xiàn)的是多樣化的編程風(fēng)格,Ceylon并沒有什么不同。Ceylon是一種靜態(tài)類型語言(statically typed language)(即 類型檢查是在編譯時進行的,相對應(yīng)的是諸如Lisp一類的動態(tài)類型語言,這些語言的類型檢查是在運行時進行的)。Ceylon是一種面向?qū)ο蟮恼Z言,類似 Java語言,其還使用典型的C語法風(fēng)格來支持高階函數(shù)(higher-order function)(即函數(shù)可以使用其他函數(shù)來作為輸入和輸出)。Java語言并不直接支持高階函數(shù),因此這一功能特性代表了這兩種語言之間獨特的不同之 處。
然而,有時候,改進更多指的是語言刪減了什么而不是添加了什么。Ceylon簡化并刪減了Java語言的一些元素,使用更簡單的方案來代替它們。 簡化的一個例子是public、protected和private關(guān)鍵字的去除,Ceylon的替代做法是只包含一個shared注解,該注解定義了類 的哪一個元素是外部可見的。Ceylon還刪除了重載功能,但使用更簡單的語法來提供了一些這一功能的變通做法(比如說默認的和有序的參數(shù))。
Ceylon包含了對繼承、序列(數(shù)組(array)或是列表(list)構(gòu)造)、泛型、命名參數(shù)等的支持,它包含了運行時類型管理的一些功能(我們會在下一節(jié)中研究一個這樣的例子)。該語言目前正處在積極的開發(fā)階段,因此其最終的功能依然處于一種開放的狀態(tài)中。
Ceylon的例子說明
盡管在寫這篇文章的時候,一個公開可用的編譯器還不存在,但是Ceylon語言的結(jié)構(gòu)已被定義出來,以便能夠通過開發(fā)一些簡單應(yīng)用來研究和考慮它的用法和可讀性。本節(jié)著眼于一些用Ceylon編寫的樣例應(yīng)用,以此來說明它的結(jié)構(gòu)。
Hello World
我會使用一個“Hello World”程序來說明一個簡單程序的創(chuàng)建,該程序在顯示界面上給出一個簡單的文本串。清單1中給出的這一例子展示了一個頂層的名為hello的方法,該方法使用writeLine方法來發(fā)出一個串到標準輸出上。
清單1. 使用Ceylon編寫的Hello World程序
doc "Hello World Program"
by "Gavin King"
void hello() {
writeLine( "Hello World." );
}
需要注意的一點是,注解也會用于API文檔(類似于doxygen一類的工具),其允許你說明方法和作者(分別是doc和by注解)。
Ceylon的類型
Ceylon采用了一組傳統(tǒng)的類型,它們被實現(xiàn)成普通的類,這些類型包括:
1. Natural:無符號整數(shù),包括零
2. Integer:有符號整數(shù)
3. Float:浮點數(shù)
4. Whole:任意精度的有符號整數(shù)
5. Decimal:任意精度和任意位小數(shù)的十進制數(shù)
默認情況下,Natural、Integer和Float類型是64位的,但你可以使用small來注解它們,以指明是32位精度的。
Ceylon的類
Ceylon是一種面向?qū)ο蟮恼Z言,你使用類的概念來編寫代碼。在Ceylon中class(類)是一種類型,其封裝了一組操作(稱作方法(method))和狀態(tài)(state),而且要定義在類的對象被初始化時狀態(tài)是如何被初始化的(類初始化器(class initializer),類似于構(gòu)造函數(shù))。
一個簡單的例子會有助于你理解Ceylon的做法。清單2為一個計數(shù)器類提供了一個簡單的類,清單2使用一個可選值來定義類,這意味著用戶可以提供該值也可以不提供,它使用Type?(類型?)這 種模式來標明。類主體包含的是類初始化器而非構(gòu)造函數(shù),這一代碼定義私有變量(除非注解成shared,否則不可見),然后定義初始化邏輯。你先從查看 start變量是否存在開始,如果存在的話,其就被用作計數(shù)的初始值。你的第一個方法,被注解成shared,因此是從類外部可見的,其定義了增量器。在 調(diào)用時,這一方法簡單地遞增你的計數(shù)器。
最后,定義一個getter方法來給用戶返回當前的計數(shù)器值,以及定義一個setter方法來把調(diào)用者提供的值設(shè)置當前的計數(shù)器值。需要注意的 是,這里使用了assign這一關(guān)鍵字來創(chuàng)建一個變量屬性以用于計數(shù)器值的設(shè)置。除了構(gòu)造函數(shù)的處理不同之外(代碼內(nèi)嵌在類內(nèi)部),類也不存在析構(gòu)函數(shù), 也不提供實現(xiàn)多個構(gòu)造函數(shù)的方式(這僅是不同于Java語言之處之一)。
清單2. 使用Ceylon編寫的一個簡單的類
01 doc "Simple Counting Class"
02 class Counter( Natural? start ) {
03
04 doc "Class Initializer"
05 variable Natural count := 0;
06 if (exists start) {
07 count := start;
09 }
10
11 doc "The incrementer"
12 shared void increment() {
13 count++;
14 }
15
16 doc "The getter"
17 shared Natural currentValue {
18 return count;
19 }
20
21 doc "The setter"
22 shared assign currentValue {
23 count := currentValue;
24 }
25
26 }
定義了這個簡單的類后,讓我們來看看如何在Ceylon中使用該類。清單3提供了一段使用Counter類的代碼。其開始先實例化類的一個cnt 對象,可以注意到Ceylon中沒有new這一關(guān)鍵字。新的Counter對象定義了之后,調(diào)用increment方法,然后使用getter方法來輸出 Counter的值。需要注意的是,在Ceylon中,=和:=運算符是不同的:=這一限定符只能用于不可變的值,而變量賦值則是使用:=運算符來進行 的。
清單3. 使用Counter類
01 Counter cnt = Counter(1);
02 cnt.increment();
03 writeLine( c.currentValue );
Ceylon鼓勵盡可能使用不變的屬性,這意味著一個對象使用某個值初始化后不會再次被賦值。要指明一個命名變量是可變的(在初始化之后可改變),其必須要使用variable注解,如清單2中第5行所展示的那樣。
最后要研究的一項是Ceylon在控制結(jié)構(gòu)方面的一個主要區(qū)別。你應(yīng)該有注意在許多的語言中,條件表達式后面的花括號({})可省略,比如說如果只出現(xiàn)單條語句的話:
if (cnt > 10) statement();
Ceylon不允許這種語法,其要求給出花括號,即上面顯示的示例代碼在Ceylon中要這樣寫:
if (cnt > 100) { statement(); }
因為這代表了C中最常見的一種錯誤,因此特別地強制使用這一正確風(fēng)格是可讓人接受的。
高階函數(shù)
Ceylon包括了被稱作一階函數(shù)(first-order function)的 函數(shù)式編程風(fēng)格,這簡單地意味著函數(shù)被視為第一類對象(first class object),其可被用作函數(shù)的參數(shù),以及可以從函數(shù)中返回。拿King為repeat方法的定義所提供的演示例子(參見清單4)來看好了。在這種情況 下,方法用到了兩個參數(shù):作為重復(fù)次數(shù)的Natural,以及要調(diào)用的一個函數(shù)的方法參數(shù)。repeat方法的方法體內(nèi)部簡單地創(chuàng)建了一個for循環(huán)(使 用了一個范圍運算),然后調(diào)用作為函數(shù)參數(shù)傳進來的方法。
清單4. Ceylon中的高階函數(shù)
01 void repeat( Natural times, void hfunction() ) {
02 for (Natural n in 1..times) {
03 hfunction();
04 }
05 }
這一方法的用法很簡單,如清單5中的第7行所示,使用了不帶參數(shù)的方法名。
清單5. 在Ceylon中使用高階函數(shù)
01 void sayhello() {
02 writeLine( "Hello World." );
03 }
04
05 ...
06
07 repeat( 10, sayhello );
不像其他語言所提供的函數(shù)支持,Ceylon不支持匿名函數(shù)(直接出現(xiàn)在表達式中的無名函數(shù)),但它支持閉包(closure)(其本質(zhì)上是能夠引用另一個函數(shù)中的狀態(tài)的函數(shù))
類型窄化
Ceylon不包含出現(xiàn)在Java語言中的instanceof運算符;其也不包含諸如可在C中找到的那種類型轉(zhuǎn)換,Ceylon的替代做法是,其實現(xiàn)了所謂的類型窄化(type narrowing), 這種做法被用來在一步中測試并縮窄對象引用的類型??紤]一下下面清單6中的代碼段,該段代碼使用了一個特殊的(is ...)構(gòu)造來測試一個對象引用是否為給定的類型,如果類型被確定的話,類型特定的方法接著就會被調(diào)用。這一構(gòu)造類似于你之前在用于說明可選參數(shù)的清單2 中見到的(exists ...)這一構(gòu)造。
清單6. Ceylon中的類型窄化
01 Object obj = ;
02
03 switch (obj)
04
05 case (is Counter) {
06 obj.increment();
07 }
08 case (is ComplexCounter) {
09 obj.incrementBy(1);
10 }
11 else {
12 stream.writeLine("Unknown object");
13 }
Ceylon包含了另一種類似的定義成(nonempty ...)的構(gòu)造,你可以把該構(gòu)造應(yīng)用在序列(數(shù)組或列表)上,以確定序列中是否是不包含有元素的,這樣就可以不用在其之上執(zhí)行操作。
最后要注意的一點是,Ceylon的switch語句的語法,其不同于C和Java語言兩者。這兩種語言中的這一語句都很容易出錯,Ceylon 在case上強制使用塊結(jié)構(gòu),并去除了default這種情況,代以else塊。Ceylon還(在編譯時)確保switch語句包含了一個詳盡的實例測 試清單,或者至少有一個else語句提供完整的覆蓋。編譯器自動檢查這些switch語句并且如果有實例沒被覆蓋到的話就產(chǎn)生一個錯誤。
其他的控制結(jié)構(gòu)
Ceylon實現(xiàn)了傳統(tǒng)的if...else語句,正如你所期望的那樣,它也實現(xiàn)了Java語言的異常處理功能(try、catch、 finally)。Ceylon還創(chuàng)建了所謂的fail塊,其和for循環(huán)一起使用以識別循環(huán)何時被提早打斷。考慮一下清單7中展示的例子。
清單7. 說明Ceylon的fail塊
01 for (Instrument i in instruments) {
02 if (i.failing()) {
03 break;
04 }
05 }
06 fail {
07 // Take some action...
08 }
這在C和Java語言中都是常見的設(shè)計模式,因此對Ceylon來說是一個有益的補充。
Ceylon的前景
正如King所說的那樣,Ceylon是社區(qū)的努力成果,因此需要軟件工程師和測試人員來幫助設(shè)計、構(gòu)建和驗證語言和SDK。這一號召能夠鼓勵 Java語言用戶做出反饋,這有助于支持他們從該語言到Ceylon的遷移。King依然對Ceylon的當前狀態(tài)保持適當?shù)某聊?,只是說語言規(guī)范以及 ANTLR(Another Tool for Language Recognition)語法都已存在了。
展望未來
盡管有些人會質(zhì)疑一種新語言的必要性,不過另一種看待語言的觀點是把它們作為用來解決問題的一系列工具。并非每一種語言都是任何指定問題的適 合的或是理想的解決工具的,但某些語言本身能夠很好的適用于某些特定的解決方案領(lǐng)域;因此,有多種語言可用是一種福氣,而非禍端。因為Ceylon仍處于 開發(fā)階段,因此其是否能夠在目前正在使用的主流語言行列中找到一個位置還是未知的。不過該語言捕捉了足夠多的興趣點,因此等其最終出現(xiàn)時,對其進行進一步 的研究將會是一件很有趣的事情。
資源
學(xué)習(xí)資料
1. Gavin King最初對Ceylon語言的介紹,可觀看這一30分鐘的標題為 Introducing the Ceylon Project的視頻。現(xiàn)有兩個來自King的Ceylon演示,包括介紹性的發(fā)言和一個標題為The Ceylon Type System的演示,該演示涵蓋了一些更先進的功能特性。
2. Gavin King提供的一個由11部分組成的描述Ceylon語言的文章系列。正如你會從針對該系列的每個元素的評論中看到的那樣,有著相當數(shù)量的反饋,并對語言進行了動態(tài)的裁剪,以此彌補所發(fā)現(xiàn)的問題。你可以在King的博客中找到這一系列文章。
3. 想要關(guān)注(和參加)Ceylon的實時構(gòu)建的話,可查看Ceylon核心團隊的郵件列表。
4. ANTLR是一種語言工具和框架,其被用來從語法描述中構(gòu)建編譯器、解釋器、翻譯器和識別器。ANTLR出自舊金山大學(xué)(University of San Francisco),基于Terence Parr的工作成果。
5. 該篇文章提及Ceylon中實現(xiàn)的一些函數(shù)式編程的功能特性??稍赪ikipediaz中找到第一類函數(shù)(first-class function)、高階函數(shù)(higher-order function)和閉包(closure)的介紹。
6. 在developerWorks Linux zone上可找到數(shù)百篇how-to文章和教程,以及下載資源和討論論壇等,還有為Linux開發(fā)者和管理員提供的其他豐富的資源。
7. 隨時關(guān)注developerWorks technical events and webcasts,了解各種IBM產(chǎn)品和IT行業(yè)主題。
8. 加入a free developerWorks Live! briefing,快速獲悉IBM的產(chǎn)品和工具,以及IT行業(yè)的發(fā)展趨勢。
9. 觀看developerWorks>