在与 Martin Fowler 共同参加的一次主题演讲中,他提供了一个敏锐的观察报告:
Java 的遗产是 平台,不是 语言。
最初的 Java 技术工程师曾做过一个了不起的决定,将语言从运行时中分离出来,最终使 200 多种语言可在 Java 平台上运行。该基础架构对平台保持长久活力非常关键,因为计算机编程语言的寿命通常很短。自 2008 年以来,每年由 Oracle 主办的 JVM 语言峰会都会为 JVM 上替代语言的实现者提供与平台工程师公开合作的机会。
欢迎来到 Java 下一代专栏系列。在这里,我将简要介绍三种现代 JVM 语言:Groovy、Scala 和 Clojure,它们将范式、设计选择和舒适因素进行了有趣的组合。我不打算在这里详细介绍每种语言;它们各自的网站上都有这方面的介绍(参阅 参考资料)。但语言社区网站(主要目的是福音传道)上没有提供语言不适应的客观信息或任务示例。在本系列文章中,我将进行实质性对比,帮助填补这项空白。本文准备概述 Java 下一代语言以及学习这些语言的好处。
超越 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()
清单 1 中,sumOfFactors方法的结果是自动缓存的。您也可以使用另一种方法自定义缓冲行为,比如 memoizeAtLeast()和 memoizeAtMost()。Clojure 还提供了备忘功能,这对 Scala 的实现是无足轻重的。下一代语言(以及一些 Java 框架)中的高级特性(比如备忘功能)将逐渐找到它们进入 Java 语言的方法。Java 的下一个版本将增加高阶函数,使备忘功能的实现变得更容易。通过学习下一代 Java 语言,提前了解未来 Java 特性。