Linux 和开放源码常常与语言设计的最新成果密切相关。原因可能是支持语言开发的众多工具或平台的开放性促进了语言设计的发展,也可能是基于开放源码技术的开放语言(比如 GNU Compiler Collection 系列、Ruby、Python 和 Perl)非常出色,吸引了开发人员,并鼓励他们进行试验和应用(更不用提 Ceylon 背后是强大的 Red Hat)。无论由于什么原因,Linux 开发人员都可以使用许多种语言,从很少有人使用的陈旧语言直到最新的尖端语言。
既然已经有了 C/C++、Java™、Scala、Ruby、Python、Perl、Erlang、Lua、Scheme 和其他许多语言,我们还要关注以面向业务企业软件开发为重点的新语言吗?在许多情况下不需要,但是我们来研究一下 Red Hat 未来的语言 Ceylon,看看它是否会取得当今最流行的语言那样的地位。
Ceylon 是由 Gavin King 领导的 Red Hat 新项目。King 是 Hibernate 项目(用 Java 编写的持久化解决方案)的创始人。尽管 King 是 Java 技术的支持者(Java 是适合大规模开发的第一批语言之一),但是他注意到 Java 有许多问题,包括泛型等特性的复杂性、设计粗糙且晦涩难懂的 Standard Edition SDK、粗劣的注解语法、不完善的块结构、对 XML 的依赖性等等。
因此,King 提出了一个问题:根据从 Java 语言和 SDK 的优缺点中学到的经验教训,应该设计出一种什么样的语言?他用 Ceylon 回答了这个问题。Ceylon 是一种静态类型语言,它保留了一些最好的 Java 语言特性(在 JVM 上运行),改进了语言的可读性和内置的模块性,还吸收了高阶函数等函数语言特性,此外,Ceylon 还融合了 C 和 Smalltalk 的一些特性。与 Java 语言一样,这种新语言也以业务计算为重点,但是它在其他领域也很灵活、很有用。
一些人把 Ceylon 称为“Java 杀手”(可能是因为对 Java 语言的未来有质疑),但是,Ceylon 实际上也是在 JVM 上运行,所以它是 Java 技术的扩展而不是替代品。使用 JVM 来支持 Ceylon 的执行是一种理想模型,因为这意味着 Ceylon 代码(与 Java 一样)可以很方便地跨目前支持 JVM 的大多数架构进行迁移。
很难将当今的大多数语言简单地归为一种类别,它们的编码风格往往是各种各样的。Ceylon 也一样。Ceylon 是一种静态类型语言,这意味着在编译时要执行类型检查;与其相反的 Lisp 等动态类型语言 会在运行时执行类型检查。与 Java 语言一样,Ceylon 是一种面向对象的语言。它还支持使用典型的 C 语法风格的高阶函数(这意味着这些函数可以采用函数作为输入或输出)。在 Java 语言中,不直接支持高阶函数,所以这个功能是这两种语言之间的重大差异。
但是,有时候语言的改进更多地体现在它取消了什么内容,而不是增加了什么。Ceylon 简化和取消了 Java 语言的一些元素,代之以更简单的方案。简化的例子之一是取消了 public、protected 和 private 关键字。Ceylon 仅包含括 shared 注解,该注释定义了类的哪些元素是外部可见的。Ceylon 还取消了重载功能,但是提供了此功能的使用更简单语法的替代方法(比如默认和顺序的参数)。
Ceylon 支持继承、序列(数组或列表构造)、泛型、命名参数等等。它包含用于运行时类型管理的特性(在下一节中将研究它的一个示例)。这种语言还在开发过程中,所以最终的特性集可能有变动。
尽管到撰写本文时还没有一个公开可用的 Ceylon 编译器,但是 Ceylon 语言的结构已经确定了,所以可以通过开发示例应用程序来研究和推断它的用法和可读性。本节将研究一些用 Ceylon 编写的示例应用程序,以此说明它的结构。
我使用 "Hello World" 程序演示如何创建简单的程序,将一个简单的文本字符串发送到显示器。清单 1 中的示例给出一个名为 hello 的顶级方法,它使用 writeLine 方法将字符串发送到标准输出。
清单 1. 用 Ceylon 编写的 Hello World 程序
doc "Hello World Program"
by "Gavin King"
void hello() {
writeLine( "Hello World." );
}
|
还要注意用于 API 文档的注解(与 doxygen 等工具相似),可以通过这些注释指定方法和作者(分别使用 doc 和 by 注解)。
Ceylon 包含一组传统的类型,它们作为普通的类实现。这些类型是:
Natural。无符号整数,包括零Integer。有符号整数Float。浮点数Whole。任意精度的有符号整数Decimal。任意精度和任意规模的小数
在默认情况下,Natural、Integer 和 Float 类型是 64 位的,但是可以通过给它们加上 small 注解来指定 32 位精度。
因为 Ceylon 是面向对象的语言,所以可以使用类的概念来编写代码。类 是 Ceylon 中的一个类型,它封装了初始化类的某个对象时如何初始化状态的定义,还封装了一组操作(称为方法)和状态,(类初始值设定项 与该构造函数相似)。
提供一个简单的类有助于您了解 Ceylon 的方法。清单 2 提供了用于计数器类的一个简单的类。第 2 行用一个可选值来定义类,这意味着用户可以提供该类,也可以不提供,这用 Type? 方法来表示。类的主体包含类初始设定项,而不是构造函数。这段代码定义私有变量(除非注释为 shared 的,否则所有元素都是不可见的),然后定义初始化逻辑。首先检查 start 变量是否存在。如果存在,则使用它作为初始计数值。第一个方法被注解为 shared,因此可以在这个类以外的地方看到它,它定义了递增操作。调用这个方法时,它会递增计数器的计数。
最后,定义 getter 方法(把当前的计数器值返回给调用者)和 setter 方法(用调用者提供的值设置当前的计数器值)。注意,这里使用 assign 关键字创建一个变量属性,用它设置计数器值。除了处理构造函数的方式不同(代码嵌套在类中)之外,没有析构函数,也无法实现多个构造函数(这是与 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 关键字。在定义了新的 Counter 对象之后,请调用 increment 方法,然后使用 getter 方法获得 Counter 值。注意,在 Ceylon 中 = 和 := 操作符是不同的:= 只用于指定不可变的值,而用 := 操作符则可以执行变量赋值。
清单 3. 使用 Counter 类
01 Counter cnt = Counter(1); 02 cnt.increment(); 03 writeLine( c.currentValue ); |
Ceylon 鼓励尽可能使用不可变的属性。这意味着用一个值初始化对象,以后不再重新赋值。要想指定某个指定值是可变的 (在初始化后可以修改),必须添加注释 variable,参见 清单 2 中的第 5 行。
最后要研究的是 Ceylon 控制结构中的一个关键差异。注意,在许多语言中,可以省略条件表达式后的花括号 ({}),比如下面所示的 statement 语句:
if (cnt > 10) statement(); |
Ceylon 不允许使用这种语法,要求必须包含花括号。这意味着上面的示例代码在 Ceylon 中必须写成:
if (cnt > 100) { statement(); }
|
因为省略花括号是 C 中最常见的错误之一,所以强制使用这种正确的编码样式的做法很受人们欢迎。
Ceylon 包含称为一阶函数 的函数式编码样式。这意味着将函数用作高级对象,还可以用作函数的参数,从函数中返回。以 King 文章中的 repeat 方法定义为例(参见清单 4)。在这种情况下,它有两个参数:一个 Natural(表示要重复的次数)和一个方法参数(表示要调用的函数)。在 repeat 方法主体内,只需创建一个 for 循环(使用范围操作)并调用作为方法参数来传递的函数即可。
清单 4. Ceylon 中的高阶函数
01 void repeat( Natural times, void hfunction() ) {
02 for (Natural n in 1..times) {
03 hfunction();
04 }
05 }
|
使用这个方法很简单,参见清单 5 的第 7 行。如下所示,所使用方法的名称中没有参数。
清单 5. 在 Ceylon 中使用高阶函数
01 void sayhello() {
02 writeLine( "Hello World." );
03 }
04
05 ...
06
07 repeat( 10, sayhello );
|
与支持函数编程的其他语言不同,Ceylon 不支持匿名函数 (直接出现在表达式中的未命名函数)。它支持闭包(实质上是可以在另一个函数中引用状态的函数)。
Ceylon 不包含 Java 语言中的 instanceof 操作符;也不包含 C 中的类型转换。相反,Ceylon 实现所谓的类型收缩 (type narrowing),使用它在一个步骤中检查并减少某个对象的引用类型。请考虑清单 6 中的代码片段。该代码使用特殊的 (is ... ) 构造检查某个对象引用是否是给定的类型。确定类型之后,则会使用与该类型有关联的方法。这个构造与 清单 2 中用来处理可选参数的 (exists ...) 构造相似。
清单 6. Ceylon 中的类型收缩
01 Object obj = <some object>;
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 ...),可以对序列(数组或列表)应用它,判断序列是否不包含元素,因此不能应用序列操作。
最后注意,Ceylon 中 switch 语句的语法与 C 和 Java 语言不同。在这两种语言容易出错的地方,Ceylon 要求所有格有严格的块结构,取消了 default 所有格,保留了 else 块。Ceylon 还确认(在编译时)switch 语句包含详尽的实例测试列表,至少包含 else 子句,从而提供完整的覆盖范围。编译器自动地检查这些 switch 语句,如果没有覆盖某个实例,会产生错误。
Ceylon 实现传统的 if...else 语句,还实现 Java 语言的异常处理特性(try、catch、finally)。Ceylon 还创建了 fail 块,在 for 循环中使用它处理循环提前中断的情况。请考虑清单 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 语言中常见的设计模式,因此在 Ceylon 中增加它是很有用的。
正如 King 指出的,Ceylon 是一个社区项目,需要软件工程师和测试人员帮助设计、构建和检验这种语言和 SDK。这个号召会鼓励 Java 语言用户提出反馈,帮助支持他们从 Java 迁移到 Ceylon。King 仍然没有明确说明 Ceylon 的现状,只是说明语言规范和 ANTLR (Another Tool for Language Recognition) 句法已经存在了。
尽管一些人可能会质疑新语言的必要性,但是应该把语言看作可以用来解决问题的工具集。并非每种语言都适合解决任何问题,但是某些语言非常适合特定的解决方案领域;因此,可以使用多种语言是好事。因为 Ceylon 仍然在开发过程中,还不确定它是否会成为流行的语言。但是,这种语言提供很多让人感兴趣的特性,当最终确定该语言中包含的特性时,有必要深入研究一下这些特性。
学习
-
可以在 30 分钟的视频 Introducing the Ceylon Project Video 中看到 Gavin King 对 Ceylon 语言的原始介绍。King 还有两篇关于 Ceylon 的文章,introductory presentation 和 The Ceylon Type System(讨论一些比较高级的特性)。
-
Gavin King 提供了一个由 11 部分组成的系列文章,对 Ceylon 语言进行了描述。从该系列的每一部分的评论中可以看出,用户的反馈相当多,语言的开发者正在积极解决发现的问题。可以在 King 的博客 上找到这个系列。
- 要想了解(和参与)Ceylon 的实时构造,请查阅 Ceylon 核心团队邮件列表。
-
ANTLR 是一种语言工具和框架,用于根据句法描述构建编译器、解释器、转换器和识别器。ANTLR 是 University of San Francisco 以 Terence Parr 的成果为基础开发的。
-
本文提到了 Ceylon 中实现的一些 函数编程 特性。查阅 Wikipedia 上对 第一等函数、高阶函数 和 闭包 的介绍。
-
参加 developerWorks Live! 技术讲座,以及时获取最新的 IBM 产品、工具以及 IT 行业趋势的信息。
-
观看 developerWorks 演示中心,包括面向初学者的产品安装和设置演示,以及为经验丰富的开发人员提供的高级功能。
- 在 developerWorks Linux 专区 寻找为 Linux 开发人员(包括 Linux 新手入门)准备的更多参考资料,查阅我们 最受欢迎的文章和教程。
- 在 developerWorks 上查阅所有 Linux 技巧 和 Linux 教程。
- 随时关注 developerWorks 技术活动和网络广播。
获得产品和技术
-
以最适合您的方式 IBM 产品评估试用版软件:下载产品试用版,在线试用产品,在云环境下试用产品,或者在 IBM SOA 人员沙箱 中花费几个小时来学习如何高效地实现 Service Oriented Architecture。
讨论
- 加入 developerWorks 中文社区,developerWorks 社区是一个面向全球 IT 专业人员,可以提供博客、书签、wiki、群组、联系、共享和协作等社区功能的专业社交网络社区。
