Java groovy和scala,Scala 的未来会怎样

酷勤网 C 程序员的那点事!
当前位置: >
浏览次数:次
近些年,基于JVM语言的发展风起云涌, 语言尤为抢眼。我们不妨从以下几个方面来介绍下Scala语言的发展前景:
Scala语言的起源
Scala语言源自瑞士洛桑联邦理工学院,由奥德斯基教授2001年带领小组致力于Scala语言、标准库和编译器的开发。这里透露一个小花絮,奥德斯基教授创建Scala语言的一个主要原因是不满Java语言相对复杂的语法。
Scala语言的发展现状
Scala语言最直接的好处是兼容Java,这就意味着可以无缝使用所有Java的类库和框架。Scala程序会被编译成JVM可执行的字节码。Scala虽然是静态语言,但Scala支持函数式编程和类型推断(Type Inference),它的哲学是结合面向对象和面向过程并保证代码的简洁。
Scala语言在生产环境和公司的普及度非常高:
Linkedin公司把高吞吐量的分布式发布订阅消息系统捐给Apache基金,该系统完全由Scala语言开发。
Twitter为了性能考虑,将部分现有用Ruby On Rails实现的系统,迁移到了Scala。
英国卫报为了提高开发效率,已经从Java切换到Scala,详情请见InfoQ相关。
使用Scala的公司非常多,详情见Scala in the Enterprise。
与此同时,Scala语言也有强大的社区作为后盾,Scala为不同的角色(初学者、有经验者、专家)提供了学习资源分享、邮件列表订阅、加入google groups、加入开放项目等方式,使得每个人都可以共享Scala的信息并将所学知识回馈到社区中去。
业界专家对Scala的评价
Java之父James Gosling在一个社区会议上,有人问James Gosling,除了Java,你还使用哪些构建在JVM上的语言?
James回答:Scala
Groovy创始人James Strachan于2009年James Strachan就在博客上写道,如果我早点看介绍Scala的那本书,就不会创立Groovy这门语言了(大家应该知道,Groovy也是门优秀的构建在JVM上的语言)
Scala语言的优雅和简洁,大家可以通过官方网站的一一体会。
其他JVM语言的发展现状
Groovy: 语法简单,开发者可以更快的学习该语言,并且非常适合开发DSL(领域特定语言)。运维Groovy的发展,让人对Groovy充满希望。
JRuby: JRuby是面向Ruby的解释程序,该程序可以实现对Java类的交互。由于Sun公司JRuby的开发人员因为不知道甲骨文是否支持JRuby而选择了跳槽,这让JRuby的发展非常的不确定。
Jython: Jython是纯Python语法的Java实现,Jython可以极大减少代码量。Jython的发展比较曲折,负责开发Jython的人员经常更换,甚至出现开发放缓的情况。后来终于得到Sun公司(已被Oracle收购)的支持,开发进度稳步增长,我们将拭目以待。
Scala语言学习&&展望
Scala开发工具非常成熟,初学者可以轻松学习Scala
Eclipse插件的形式:Scala IDE v2.0已经。
Scala官网推荐的工具
独立IDE:评价最高的Scala IDE,。
社区版已经可以集成Scala插件。
Scala语言的发展路线可以总结为两点:
第一,Scala语言旨在成为最为普及的JVM语言(这点已经做到),并不断完善语言特性加强语言的生产力。
第二,Scala语言会涉足其他非JVM平台,使得非Java程序员也可以体验Scala的优雅,比如Scala已经可以在.Net上运行。
相信Scala语言会在未来给我们不断的惊喜!
& 相关主题:
本文来源:IBM Bluemix
点击按钮,开始云上的开发!
developerWorks 社区
与 Java™ 语言相关的常见抱怨包括:简单的任务涉及到太多的步骤,默认设置有时难以理解。所有 3 种 Java 下一代语言在这些领域都采取了更加明智的方法。这一期
展示了 Groovy、Scala 和 Clojure 如何消除 Java 语言的瑕疵。
, Director / Software Architect / Meme Wrangler, ThoughtWorks Inc.
Neal Ford 是一家全球性的 IT 咨询公司 ThoughtWorks 的主管、软件架构师和 Meme Wrangler。他还设计并编写了一些应用程序、教材、杂志文章、课件和视频/DVD演示文稿,他是多种技术书籍的作者或编辑,其中包括最近出版的这本 。他的工作重点是设计和构建大型企业级应用程序。他还是全球范围开发者大会上的一位国际知名的演讲者。您可以查看 。
Java 编程语言诞生时所面临的限制与如今的开发人员所面临的条件有所不同。具体来讲,由于上世纪 90 年代中期的硬件的性能和内存限制,Java 语言中存在原语类型。从那时起,Java 语言不断在演化,通过自动装箱(autobox)消除了许多麻烦操作,而下一代语言(Groovy、Scala 和 Clojure)更进一步,消除了每种语言中的不一致性和冲突。
在这一期的文章中,我将展示下一代语言如何消除一些常见的 Java 限制,无论是语法上还是默认行为上。第一个限制是原语数据类型的存在。
原语的消亡
Java 语言最开始有 8 对原语和相应的类型包装器类(最初用于解决性能和内存限制),并通过自动装箱逐步地淡化了它们之间的区别。Java 下一代语言更进一步,让开发人员觉得好像根本不存在差别。
Groovy 完全隐藏了原语类型。例如,int 始终表示 Integer,Groovy 自动处理数字类型的上变换,防止出现数值溢出错误。例如,请查看清单 1 中的 Groovy shell 交互:
清单 1. Groovy 对原语的自动处理groovy:000& 1.class
===& class java.lang.Integer
groovy:000& 1e12.class
===& class java.math.BigDecimal
中,Groovy shell 显示,即使是常量也是通过底层的类来表示的。因为所有数字(和其他伪装的原语)都是真正的类,所以可以使用元编程技术。这些技术包括将方法添加到数字中(这通常用于构建特定领域的语言,即 DSL),支持 3.cm 这样的表达式。在后面介绍可扩展性的那期文章中,我会更全面地介绍此功能。
与 Groovy 中一样,Clojure 自动屏蔽原语与包装器之间的区别,允许对所有类型执行方法调用,自动处理容量的类型转换。Clojure 封装了大量底层优化,这已在语言文档中详细说明(参阅 )。在许多情况下,可提供类型 hints,使编译器能够生成更快的代码。例如,无需使用 (defn sum[x] ... ) 定义方法,可以添加一个类型提示,比如 (defn sum[^float x] ... ),它会为临界区 (critical section) 生成更高效的代码。
Scala 也屏蔽了原语之间的区别,通常对代码的时效性部件使用底层原语。它还允许在常量上调用方法,就像 2.toString 中一样。借助其混搭原语和包装器的能力,比如 Integer,Scala 比 Java 自动装箱更加透明。例如,Scala 中的 == 运算符可在原语和对象引用上正确运行(比较值,而不是引用),而不同于相同运算符的 Java 版本。Scala 还包含一个 eq 方法(以及一个对称的 ne 方法),它始终比较底层引用类型是否等效。基本而言,Scala 会智能地切换默认行为。在 Java 语言中,== 会对引用数据进行比较,您几乎不需要这么做,可以使用不太直观的 equals() 比较值。在 Scala 中,== 能正确运行(比较值),无论底层实现是什么,它还提供了一个方法来执行不太常见的引用相等性检查 (reference equality check)。
Scala 的这一特性表明,Java 下一代语言的一个重要优势在于:将低级细节卸载到语言和运行时,开发人员能够有更多的时间考虑更高级的问题。简化默认行为
人们的看法高度一致,大部分 Java 开发人员都认为,在 Java 语言中常见的操作需要太多的语法。例如,属性定义和其他样板代码使类定义变得很杂乱,掩盖了重要的方法。所有 Java 下一代语言都提供了简化创建和访问过程的途径。
Scala 中的类和 case 类
Scala 已简化了类定义,可为您自动创建存取函数、赋值函数和构造函数。例如,请查看清单 2 中的 Java 类:
清单 2. Java 中简单的 Person 类class Person {
Person(String name, int age) {
this.name =
this.age =
public String getName() {
public int getAge() {
public void setAge(int age) {
this.age =
public String toString() {
return name + " is " + age + " years old.";
} 中惟一的非样板代码是改写的 toString() 方法。构造函数和所有方法都由 IDE 生成。相比快速生成代码,在以后轻松理解它更为重要。无用的语法增加了您在理解底层含义之前必须使用的代码量。
Scala Person 类
令人震惊的是,清单 3 中用 Scala 编写的简单 3 行定义就创建了一个等效的类:
清单 3. Scala 中的等效类class Person(val name: String, var age: Int) {
override def toString = name + " is " + age + " years old."
} 中的 Person 类浓缩成了一个可变的 age 属性、一个不可变的 name 属性,以及一个包含两个参数的构造函数,还有我改写的 toString() 方法。很容易看到这个类的独特之处,因为有趣的部分没有埋藏在语法中。
Scala 的设计强调了以最少的语法创建代码的能力,它使许多语法成为可选语法。清单 4 中的简单类演示了一个将字符串更改为大写字母的 Verbose 类:
清单 4. Verbose 类class UpperVerbose {
def upper(strings: String*) : Seq[String] = {
strings.map((s:String) =& s.toUpperCase())
} 中的许多代码都是可选的。清单 5 给出了相同的代码,现在使用了一个 object 而不是 class:
清单 5. 一个转换为大写的更简单的对象object Up {
def upper(strings: String*) = strings.map(_.toUpperCase())
对于等效于 Java 静态方法的 Scala 代码,可创建一个 object(与独体实例等效的 Scala 内置实体)而不是一个类。方法的返回类型、用于将单行方法主体分开的括号,以及
中无用的 s 参数都从
中消失了。Scala 中的这种 “可折叠语法” 有利有弊。使用可折叠语法,能够以非常符合语言习惯的方式编写代码,但这让不熟悉的人难以理解您的代码。
用作数据持有者的简单类在面向对象的系统中很常见,尤其是必须与不同系统通信的系统。这种类型的类的流行使得 Scala 项目向前推进了一步,创造了 case 类。case 类自动提供了多种便捷的语法:
可根据该类的名称创建一个工厂方法。例如,可以在不使用 new 关键字的情况下构造一个新实例:val bob = Person("Bob", 42)。
该类的参数列表中的所有参数都自动 val,也就是说,它们是作为不可变的内部字段来维护的。
编译器为您的类生成合理的默认 equals()、hashCode() 和 toString() 方法。
编译器将一个 copy() 方法添加到类中,以便您可返回某个副本来执行变体式更改。Java 下一代语言不仅修复了语法瑕疵,还促进了对现代软件工作原理的更准确的理解,朝这个方向塑造它们的工具。Groovy 的自动生成属性在 Java 下一代语言中,Groovy 与 Java 语法最接近,为常见情形提供了称为 “语法糖 (syntactic-sugar)” 的代码生成方法。参见清单 6 中简单的 Groovy Person 类:
清单 6. Groovy Person 类class Person {
private name
def getName() {
String toString() {
"${name} is ${age} years old."
def bob = new Person(name: "Bob", age:42)
println(bob.name)
的 Groovy 代码中,定义一个字段 def 会得到一个存取函数和赋值函数。如果仅喜欢其中一个函数,可自行定义它,就像我对 name 属性所做的那样。尽管该方法名为 getName(),但我仍然可以通过更直观的 bob.name 语法访问它。
如果希望 Groovy 自动为您生成 equals() 和 hashCode() 方法对,可以向类中添加 @EqualsAndHashCode 注释。该注释使用 Groovy 的抽象语法树 (Abstract Syntax Tree, AST) 转换 生成基于您的属性的方法(参阅 )。在默认情况下,此注释仅考虑属性(而不考虑字段);如果添加了 includeFields=true 修饰符,它也会考虑字段。
Clojure 的映射式记录
可在 Clojure 中像其他语言中一样创建相同 Person 类,但这并不符合语言习惯。传统上,Clojure 等语言依靠映射(名称-值对)数据结构来持有这种类型的信息,并使用了一些处理该结构的函数。尽管仍然可以在映射中建模结构化的数据,但目前更常见的情形是使用记录。记录是 Clojure 对具有属性(常常是嵌套的)的类型名的更加正式的封装,每个实例具有相同的语义含义。(Clojure 中的记录就像类 C 语言中的 struct。)
例如,请考虑以下人员定义:
(def mario {:fname "Mario"
:age "18"})
鉴于此结构,可以通过 (get mario :age) 访问 age。简单的访问是映射上的一个常见操作。借助 Clojure,可以利用使用键充当着映射上的存取函数 的语法糖,以便使用更有效的 (:age
mario) 速记法。Clojure 期望对映射进行操作,所以它提供了大量语法糖来简化此操作。
Clojure 还拥有访问嵌套的映射元素的语法糖,如清单 7 所示:
清单 7. Clojure 的速记式访问(def hal {:fname "hal"
:address {:street "Enfield Tennis Academy"
:city "Boston"
:state "MA"}})
(println (:fname hal))
(println (:city (:address hal)))
(println (-& hal :address :city))
中,我定义了一个名为 hal 的嵌套数据结构。对外部元素的访问按预期进行 ((:fname hal))。如
中倒数第二行所示,Lisp 语法执行 “内外” 评估。首先,必须从 hal 获取 address 记录,然后访问 city 字段。因为 “内外” 评估是一种常见用法,所以 Clojure 提供了一个特殊运算符(-& thread 运算符)来反转表达式,使它们更加自然、更具可读性:(-& hal :address :city)。
可使用记录创建等效的结构,如清单 8 所示:
清单 8. 使用记录创建结构(defrecord Person [fname lname address])
(defrecord Address [street city state])
(def don (Person. "Don" "Gately"
(Address. "Ennet House" "Boston", "MA")))
(println (:fname don))
(println (-& don :address :city))
中,我使用 defrecord 创建了相同的结构,得到了一种更加传统的类结构。借助 Clojure,可以通过熟悉的映射操作和方言在记录结构中实现同样便捷的访问。
Clojure 1.2 围绕常见操作的记录定义通过两个工厂函数添加了语法糖:-&类型名称, 接收字段的位置参数-&映射-&类型名称, 字段值的关键字映射使用符合语言习惯的函数,代码由
转换成版本 .清单 9. Clojure 的漂亮的语法糖(def don (-&Person "Don" "Gately"
(-&Address "Ennet House" "Boston", "MA")))
在许多情况下,记录比映射和扁平结构更受欢迎。首先,defrecord 创建了一个 Java 类,使它更容易在多方法定义中使用。然后,defrecord 指定更多任务,在您定义记录时启用字段验证和其他细微处理。第三,记录速度快得多,尤其在您拥有一组固定的已知键的时候。
Clojure 结合使用记录和协议来构造代码。未来的一期文章将介绍它们的关系。
与 Java 语言相比,所有 3 种 Java 下一代语言都提供了更便捷的语法。Groovy 和 Scala 使构建类和常见情形更加轻松,而 Clojure 使映射、记录和类能够无缝地互操作。所有 Java 下一代语言的一个共同主旨是消除不必要的样板代码。在下一期文章中,我将继续探讨这个主题并讨论一些异常。
参考资料 (Neal Ford,developerWorks,2013 年 3 月):使用 Java 下一代语言(Groovy、Scala 和 Clojure)解决 Java 语言中无法重载运算符的问题。(Neal Ford、developerWorks,2013 年 1 月):在这篇对 Java 下一代语言及其优势进行概述的文章中,探索 3 种下一代 IVM 语言(Groovy、Scala 和 Clojure)中的异同。:Scala 是 JVM 上一种现代的函数式语言。:Clojure 是一种运行于 JVM 之上的现代的函数式语言。请参阅 Clojure
文档。:Groovy 是一种用于 JVM 的动态语言。 参阅 Groovy
文档。:跟随此知识路径,浏览有关各种替代性 JVM 语言的 developerWorks 内容。:在这个 developerWorks 系列中,Java 语言架构师 Brian Goetz 探讨了为 Java SE 7、Java SE 8 和更改版本中的 Java 语言演化带来挑战的一些语言设计问题。:在 developerWorks 上的 Neal Ford 专栏系列中探索函数式编程。(Neal Ford,developerWorks,2005 年 6 月至今):了解 Groovy、Scala、Clojure、函数式编程、架构、设计、Ruby、Eclipse 和其他 Java 相关技术。:可在这里找到数百篇关于 Java 编程的各个面面的文章。下载
或 ,动手使用来自 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 的应用程序开发工具和中间件产品。查阅 ,加入 。
developerWorks: 登录
标有星(*)号的字段是必填字段。
保持登录。
单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件。
在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。
所有提交的信息确保安全。
选择您的昵称
当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。昵称长度在 3 至 31 个字符之间。
您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。
标有星(*)号的字段是必填字段。
(昵称长度在 3 至 31 个字符之间)
单击提交则表示您同意developerWorks 的条款和条件。 .
所有提交的信息确保安全。
文章、教程、演示,帮助您构建、部署和管理云应用。
立即加入来自 IBM 的专业 IT 社交网络。
为灾难恢复构建应用,赢取现金大奖。
static.content.url=/developerworks/js/artrating/SITE_ID=10Zone=Java technology, Open sourceArticleID=930333ArticleTitle=Java 下一代: Groovy、Scala 和 Clojure 中的共同点,第 2 部分publish-date=Groovy创始人:Java面临终结 Scala将取而代之 -科技先生
科技先生-微信公众号:itechsir
Groovy创始人James Strachan前日在其博客上发表了一篇文章,题目为《Scala将取代Java /javac?》。以下是正文部分的翻译:
不要误解我的意思&&我在过去的这十来年里写了无数的Java代码,并且坚信它相对C++和Smalltalk来说是一个巨大的进步(当然,很多其它语言 也很有帮助,像JavaScript,Ruby,Groovy,Python等)。但是我还是一直期待着能有javac的替代者出现。我甚至还自创了一门 语言(编者注:此处指Groovy)好让我暂时满足一下这种期望。
Java是一种令人惊叹的复杂语言(它的语法规范长达600 页,我怀疑到底有没有人能真正理解它),它有自动装箱(Autoboxing),空指针异常(NPE)往往就是这时抛出的。其中的基本类型 (primitive type),字符串/文字/缓冲器/集合类(collections)以及数组缺乏多态性,以至于处理任何数据结构都需要冗长的语法;而且,由于Bean 属性和对闭包支持的缺失(甚至在JDK 7里也仍然还不支持),这会让你的代码里充满了 try/catch/finally 这些语句(除非你使用框架和新的自定义API)。除了这些还有好多数不清的麻烦问题。Java倒是有类型推断(type inference)功能但却不用,使得我们要多输/读如此大量的代码。
这个问题在没有Java7后变得更加紧迫 (在Snorcle之后它变得更加重要:我不知道javac是不是要被jdkc 取而代之了?)。所以我猜javac可能已经走到了尽头,它看起来根本就没有什么进展或简化了。
那么,从长久来看,谁能取代java呢?当然,像Ruby,Groovy,Python,还有JavaScript这些动态语言在过去几年里很受欢迎&&很多人喜欢他们。
我认为将来可能替代javac的就是Scala 。它实在太让我印象深刻了。我甚至可以诚实地说,如果有人在2003年把Martin Odersky,Lex Spoon以及Bill Venners写的那本《Programming in Scala》拿给我看了的话,那我根本就不会再去发明Groovy了。
那么,为什么我会看好Scala呢?Scala是静态类型的,它可以被编译成与Java同样快速的字节码,所以它的速度与Java不分上下(有时快 一点,有时慢一点)。你可以看看 Scala 在与 groovy 或jruby一起进行测试时表现有多好。注意:速度并不是我们追求的唯一目标&&有时候我们可能宁肯让代码慢上十倍,也要写得简洁一点;但是如果要取代 javac,速度当然还是很重要的。
官方微信公众号: itechsirThe page is temporarily unavailable
nginx error!
The page you are looking for is temporarily unavailable.
Please try again later.
Website Administrator
Something has triggered an error on your
This is the default error page for
nginx that is distributed with
It is located
/usr/share/nginx/html/50x.html
You should customize this error page for your own
site or edit the error_page directive in
the nginx configuration file
/etc/nginx/nginx.conf.IBM Bluemix
点击按钮,开始云上的开发!
developerWorks 社区
本文开启了一个崭新的 Neal Ford developerWorks 系列,该系列对三种下一代 JVM 语言进行了深入比较:Groovy、Scala 和 Clojure。在第 1 部分中,将了解这些语言的相似性和差异,不管您现在是否继续选择 Java™作为主要编程语言。
, Director / Software Architect / Meme Wrangler, ThoughtWorks Inc.
Neal Ford 是一家全球性的 IT 咨询公司 ThoughtWorks 的主管、软件架构师和 Meme Wrangler。他还设计并编写了一些应用程序、教材、杂志文章、课件和视频/DVD演示文稿,他是多种技术书籍的作者或编辑,其中包括最近出版的这本 。他的工作重点是设计和构建大型企业级应用程序。他还是全球范围开发者大会上的一位国际知名的演讲者。您可以查看 。
在与 Martin Fowler 共同参加的一次主题演讲中,他提供了一个敏锐的观察报告:
Java 的遗产是 平台,不是 语言。
最初的 Java 技术工程师曾做过一个了不起的决定,将语言从运行时中分离出来,最终使 200 多种语言可在 Java 平台上运行。该基础架构对平台保持长久活力非常关键,因为计算机编程语言的寿命通常很短。自 2008 年以来,每年由 Oracle 主办的 JVM 语言峰会都会为 JVM 上替代语言的实现者提供与平台工程师公开合作的机会。
欢迎来到 专栏系列。在这里,我将简要介绍三种现代 JVM 语言:Groovy、Scala 和 Clojure,它们将范式、设计选择和舒适因素进行了有趣的组合。我不打算在这里详细介绍每种语言;它们各自的网站上都有这方面的介绍(参阅 )。但语言社区网站(主要目的是福音传道)上没有提供语言不适应的客观信息或任务示例。在本系列文章中,我将进行实质性对比,帮助填补这项空白。本文准备概述 Java 下一代语言以及学习这些语言的好处。
Java 语言因 Bruce Tate 在其著作 超越 Java(参阅 )中将其称为 完美风暴而出名,导致 Java 出名的综合因素包括:Web 的兴起、现有 Web 技术因各种原因产生的不适应性,以及企业多层应用开发的兴起。Tate 也认为完美风暴是一系列独立事件,而其他语言不会以同样方式达到同样的高度。
Java 语言已证明其功能相当灵活,但人所共知,其语法和固有范式具有一定的局限性。尽管 Java 语言正在进行一些看似美好的改变,但其语法根本不支持一些重要的未来目标,如函数式编程元素。但是,如果您试图找到一种新语言取代 Java,那您就错了。
多语言编程多语言编程是我在 2006 年的一片博客文章中重新提出并推广的一个术语(参阅 ),多语言编程以单一语言并不适合解决所有问题的认知为基础的。一些语言具有更适合某些特定问题的内在特性。例如,虽然 Swing 与 Java 一样成熟,但开发人员发现在 Java 中编写 Swing UI 非常麻烦,因为它要求进行类型声明,要求行为具有匿名内部类,并且具有其他冲突因素。使用更适合构建 UI 的语言,比如带有 SwingBuilder的 Groovy(参阅 ),就会使构建 Swing 应用程序变得更容易。
JVM 上运行的语言的扩展使多语言编程的构思更具吸引力,因为您可以在维护相同的底层字节码和库时将其混搭。例如,SwingBuilder不能取代 Swing;它在现有 Swing API 上进行分层。当然,长期以来,开发人员一直混合使用 JVM 以外的语言(例如,混搭使用 SQL 和 JavaScript 来实现特定目的),这在 JVM 范围内更加普遍。许多 ThoughtWorks 项目包含多种语言,ThoughtWorks Studios 开发的所有工具均使用混合语言。
即使 Java 依旧是您的主要开发语言,也可以了解如何运行其他语言,以便在策略上使用它们。Java 依然是 JVM 生态系统的重要部分,但最终人们更倾向于将它用作平台汇编语言 —一个您可以完全了解性能或满足特定需求的地方。
20 世纪 80 年代初,在我上大学期时,我们使用称为 Pecan Pascal 的开发环境。它的独特之处是可以同时在 Apple II 或 IBM PC 上运行相同的 Pascal 代码。Pecan 工程师使用某种称为 “字节码” 的神秘东西实现了这一壮举。开发人员将他们的 Pascal 代码编译成这种 “字节码”,并在为每个平台本地编写的 “虚拟机” 上运行。多么可怕的经历啊!甚至对于简单的任务而言,生成代码也极其缓慢。当时的硬件根本无法应对这种挑战。
发布 Pecan Pascal 之后的十年,Sun 发布了 Java,Java 使用了相同的架构,对于 20 世纪 90 年代中期的硬件环境,运行该代码显得有些紧张,但最终取得了成功。Java 还增加了其他开发人员友好的特性,如自动垃圾收集。使用过像 C++ 这样的语言之后,我再也不想在没有垃圾收集的语言中编写代码。我宁愿花将时间花在更高层次上的抽象上,思考解决复杂业务问题的方法,也不愿意在内存管理等复杂的管道问题上浪费时间。
计算机语言通常不会有很长的寿命,原因之一是语言和平台设计的创新速度。随着我们的平台逐渐强大,可以处理的繁重作业也就越多。例如,Groovy 的 备忘特性(2010 年增加的特性)缓冲了函数调用结果。不需要手写缓冲代码,这可能会引入 bug,只需调用 memoize()方法即可,如清单 1 所示:
清单 1. 在 Groovy 中备忘一个函数 def static sum = { number -&
factorsOf(number).inject(0, {i, j -& i + j})
def static sumOfFactors = sum.memoize() 中,sumOfFactors方法的结果是自动缓存的。您也可以使用另一种方法自定义缓冲行为,比如 memoizeAtLeast()和 memoizeAtMost()。Clojure 还提供了备忘功能,这对 Scala 的实现是无足轻重的。下一代语言(以及一些 Java 框架)中的高级特性(比如备忘功能)将逐渐找到它们进入 Java 语言的方法。Java 的下一个版本将增加高阶函数,使备忘功能的实现变得更容易。通过学习下一代 Java 语言,提前了解未来 Java 特性。
Groovy、Scala 和 Clojure
Groovy 是 21 世纪的 Java 语法(浓缩咖啡,而非普通咖啡)。Groovy 的设计目标是更新并减少 Java 语法阻力,同时支持 Java 语言中的主要范式。因此,Groovy 需要 “了解” JavaBeans 这类技术,并简化属性访问。Groovy 快速合并新特性,并提供了一些重要函数特性,我将在后面几期中重点介绍。Groovy 在根本上依然是面向对象的命令式语言。Groovy 与 Java 的两个主要区别是,Groovy 是 ,而且它的元程序功能更佳。
Scala 是一种充分利用了 JVM 优势的语言,但其语法完全进行了重新设计。Scala 是一种强静态类型语言(比对类型要求比较严格的 Java 更严格)支持面向对象范式和函数范式,而且更青睐于后者。例如,Scala 倾向 val声明,并使不变的变量(类似于在 Java 中将参数标记为 final)服从于 var,这创建了人们更加熟悉的可变变量。通过大力支持这两种范式,Scala 为您提供了从您可能是(一名面向对象的命令式程序员)到可能应该是(一名倾向函数式的程序员)的桥梁。
Clojure 是一种 Lisp 方言,在语法上彻底背离了其他语言。它是一种强动态类型语言(和 Groovy 一样),反映了专断的设计决策。虽然 Clojure 允许您用遗留 Java 进行完整和深入的交互操作,但它并不试图构建与旧式范式相连的桥梁。例如,Clojure 不具备纠错功能,并且支持面向对象进行交互操作。但是,它还支持对象程序员所习惯的所有特性,如多态性,但它以函数方式而非面向对象的方式来实现这些特性。Clojure 围绕一些核心工程原理(比如 Software Transactional Memory)进行设计,它打破了旧的范式,支持新的功能。
除了语法之外,这些语言最有趣的不同之处在于类型和底层主要范式:函数式或命令式。
静态与动态类型
编程语言中的 静态类型指的是显式类型声明,如 Java 的 声明。动态类型指的是不要求提供类型声明信息的语言。所有语言都是 强类型语言,这意味着您的代码可以反映赋值后的类型。
Java 的类型系统饱受责备,因为它的静态类型带来了许多不便,而且无法获得较大收益。例如,在现行的有限类型推断之前,Java 要求开发人员在赋值等号的两侧重复进行类型声明。Scala 与 Java 相比是更加静态的类型,但在日常使用时并不麻烦,因为它很好地利用了类型推断。
Groovy 有一个行为,乍一看,该行为似乎架起了静态与动态之间的桥梁。请考虑清单 2 所示的简单集合工厂:
清单 2. Groovy 集合工厂 class CollectionFactory {
def List getCollection(description) {
if (description == "Array-like")
new ArrayList()
else if (description == "Stack-like")
new Stack()
} 中的类充当了一个工厂,它将根据传递的 description 参数返回两个 list 接口实现程序中的一个(ArrayList 或 Stack)。对 Java 开发人员而言,这似乎能够确保返回的结果满足规则。但是,清单 3 中的这两个单元测试显示了它带来的并发症:
清单 3. 测试 Groovy 中的集合类型 @Test
void test_search() {
List l = f.getCollection("Stack-like")
assertTrue l instanceof java.util.Stack
l.push("foo")
assertThat l.size(), is(1)
def r = l.search("foo")
@Test(expected=groovy.lang.MissingMethodException.class)
void verify_that_typing_does_not_help() {
List l = f.getCollection("Array-like")
assertTrue l instanceof java.util.ArrayList
l.add("foo")
assertThat l.size(), is(1)
def r = l.search("foo")
的第一个单元测试中,我通过工厂检索 Stack,验证它确实是 Stack,然后执行 Stack的操作,如 push()、size()和 search()。但在第二个单元测试中,我必须用 MissingMethodException 预期发生的异常,以保护测试,这样才能通过测试。在检索 Array-like 集合并将它作为一个 List 放入变量类型时,我可以证明我确实收到了一个 list。但是,当我试图调用这个 search()方法时,它会触发异常,因为 ArrayList不包括 search()方法。因此,通过提供无编译时间保护的声明,可以确保方法调用是正确的。
虽然这看起来可能像一个 bug,但它却是正确的行为。Groovy 中的类型只确保 赋值语句的有效性。例如,在 中,如果我返回一些 List 接口的内容,则会触发运行时异常(GroovyCastException)。这会让 Groovy 与 Clojure 在强动态类型家族中牢牢站稳脚跟。
然而,语言最近发生的变化已使 Groovy 中的静态和动态区分变得十分模糊。Groovy 2.0 新增了一个 @TypeChecked注释,使您能够在类或方法级别上制定严格类型检查特别决策。清单 4 举例说明了这个注释:
清单 4. 类型检查与注释 @TypeChecked
@Test void type_checking() {
def f = new CollectionFactory()
List l = f.getCollection("Stack-like")
l.add("foo")
def r = l.pop()
assertEquals r, "foo"
中,我添加了 @TypeChecked 注释,验证了赋值和随后的方法调用。例如,清单 5 中的代码不再进行 编译:
清单 5. 类型检查可防止无效的方法调用 @TypeChecked
@Test void invalid_type() {
def f = new CollectionFactory()
Stack s = (Stack) f.getCollection("Stack-like")
s.add("foo")
def result = s.search("foo")
中,我必须为工厂返回添加类型转换,以支持我调用 Stack的 search()方法。该工具与限制条件一起使用:在启用静态类型时,Groovy 的许多动态特性是无效的。但是,该示例说明了 Groovy 在建立静态和动态划分之间的桥梁时的不断变化。
所有这些语言都是十分强大的元程序编程工具,所以事后可以添加更加严格的类型。例如,有一些辅助项目可以将选择类型添加到 Clojure。但是,通常情况下,如果选择类型是可选的,那么它就不再是类型系统的一部分;它是一种验证机制。
命令式与函数式
另一个主要比照是命令式与函数式。命令式编程主要关注分步指令,在许多情况下,模仿古老的低级硬件的便利条件。函数式编程更关注一流结构函数,并试图最大程度地减少状态转换和易变性。
受 Java 影响的比较大的 Groovy 实际上是一种命令式语言。但从一开始它就包含大量函数式语言特性,随着时间的推移,还在不断添加新的特性。
Scala 将这两种范式结合起来使用并为它们提供支持。虽然函数式编程更受喜欢(并受支持),但 Scala 仍然支持面向对象的编程和命令式编程。因此,恰当使用 Scala 要求一个纪律严明的团队确保您不会将范式随意混合搭配,这在多范式语言中一直是一种危险举动。
Clojure 没有提供纠错功能。它支持面向对象的编程,以便支持与其他 JVM 语言轻松交互,但它并不会充当桥梁。相反,Clojure 的专断设计声明设计师所思考的正是良好的工程实践。那些决策影响深远,使 Clojure 能够以开创性的方式解决 Java 世界冗繁的问题(如并发性)。
了解这些全新语言所需的诸多思维转换都来自命令式 / 函数式划分,而且这是本系列文章中最有意义的探索领域之一。
开发人员生活在一个采用多种语言解决问题的语言种类越来越多的世界中。学会有效使用新语言有助于您确定某种方法何时适用。您无需抛弃 Java,它将逐渐融合下一代 JVM 语言的特性;通过了解它们,您可以窥视 Java 语言的未来。
在下一期的 Java 下一代语言中,我将开始对比 Groovy、Scala 和 Clojure 之间的共同之处。
参考资料 :对 JVM. Groovy 构建者而言,Groovy 是一种动态语言,如 简化了复杂对象的构造。:Scala 是 JVM 上的一种现代函数式语言。:Clojure 是 JVM 上运行的现代函数式 Lisp。(Bruce Tate,O'Reilly Media,2005 年):Tate 的著作讨论了 Java 的许多缺点及其生态系统。:阅读 Neal Ford 2006 年的博客文章。:跟随该知识路径了解关于各种可选 JVM 语言的 developerWorks 内容。该知识路径提供了一个优秀 Venkat Subramaniam 博士的 ,讨论了多语言编程的优劣。:在此 developerWorks 系列文章中,Java 语言架构师 Brian Goetz 探索了一些语言设计问题,并展示了 Java SE 7、Java SE 8 以及之后的 Java 语言的发展挑战。:在 Neal Ford 关于 developerWorks 的专栏系列中探索函数式编程。
浏览 阅读有关这些主题和其他技术主题的书。
:这里有数百篇关于 Java 编程各个方面的文章。
下载 或 并开始使用来自 DB2®、Lotus®、Rational®、Tivoli®和 WebSphere®的应用程序开发工具和中间件产品。
查看 并加入 。
developerWorks: 登录
标有星(*)号的字段是必填字段。
保持登录。
单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件。
在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。
所有提交的信息确保安全。
选择您的昵称
当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。昵称长度在 3 至 31 个字符之间。
您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。
标有星(*)号的字段是必填字段。
(昵称长度在 3 至 31 个字符之间)
单击提交则表示您同意developerWorks 的条款和条件。 .
所有提交的信息确保安全。
文章、教程、演示,帮助您构建、部署和管理云应用。
立即加入来自 IBM 的专业 IT 社交网络。
为灾难恢复构建应用,赢取现金大奖。
static.content.url=/developerworks/js/artrating/SITE_ID=10Zone=Java technology, Open sourceArticleID=936057ArticleTitle=Java 下一代: Groovy、Scala 和 Clojurepublish-date=

我要回帖

更多关于 groovy scala kotlin 的文章

 

随机推荐