Scala、Groovy和Clojure之间的比较

676

请问有人能够解释Scala、Groovy和Clojure这三种编程语言之间的主要区别吗?我知道它们都可以编译运行在JVM上,但我想要一个简单的对比。

6个回答

872

Groovy 是一种动态类型语言,其语法与 Java 非常接近,具有许多语法改进,可以减少样板代码,使代码更轻便。它既可以通过解释器运行,也可以编译,非常适合快速原型设计、脚本和学习动态语言,而不必学习新的语法(假设你已经了解了 Java)。自 Groovy 2.0 开始,它还具有越来越多的静态编译支持。 Groovy 支持闭包,并支持在某种程度上采用函数式编程风格,尽管它距离传统的函数式编程定义还有一定距离。

Clojure 是一种 Lisp 方言,具有一些高级功能,如 软件事务内存。如果你喜欢 Lisp,想在 JVM 上使用类似的东西,那么 Clojure 就是为你而生的。它可能是运行在 JVM 上最函数式的语言,也是最著名的一个。此外,它对不变性的重视程度比其他 Lisp 方言更高,这使它更接近函数式语言爱好者的内心。

Scala 是一种完全面向对象的语言,比 Java 更加面向对象,具有非常先进的类型系统,是非研究性语言中可用的最先进的类型系统,也是 JVM 上最先进的类型系统之一。它还结合了许多函数式语言的概念和特性,而不会损害面向对象编程,但是它在函数式语言特性上的妥协使一些后者的爱好者感到被冷落了。

Groovy在Grails中有很好的接受度和流行的Web框架。它还支持Gradle构建系统,逐渐成为Maven的受欢迎替代品。就我个人而言,与其他语言相比,特别是Jython和JRuby开始进入JVM领域,我认为它的实用性有限。

Clojure,即使不考虑一些非常有趣的功能,作为JVM上的Lisp方言也具有很强的吸引力。它可能会限制其受欢迎程度,但我期望它将拥有长时间的忠诚社区。

Scala可以直接与Java竞争,在几乎所有方面都可以与Java匹敌。当然,它当前无法在受欢迎程度上与Java竞争,并且缺乏强大的企业支持可能会阻碍它在企业环境中的接受度。它还比Java更加动态化,从语言的角度来看,这是一个好事情。但对于计划使用数千行代码编写的用户而言,则不尽然。

最后披露一下,我非常熟悉Scala,只是略知其他两种语言。


1
不错。虽然我必须说Scala有Lightbend公司的支持,并且被LinkedIn、Twitter、Spark和许多银行等大公司使用。在我工作的地方,我们有一个1100万行Scala代码库,这并不是一个好主意,但它确实有效。 - Joan

219

Scala

Scala起源于一种纯函数式语言Funnel,几乎实现了Java的所有语法,只有在可以明显改进或者可能破坏语言的函数性质时才有所不同。这些差异包括单例对象而不是静态方法和类型推断。

其中很多都基于Martin Odersky与Pizza语言的先前工作。面向对象/函数式编程的集成远远超出了闭包的范畴,并且导致该语言被描述为后函数式。

尽管如此,在许多方面它都是最接近Java的。主要是由于OO支持和静态类型,但也由于语言设计中明确的目标,即它应该与Java密切集成。

Groovy

Groovy通过两种方式明确解决了Java的两个最大批评问题:

  • 动态类型化,从而消除了很多样板文件;
  • 将闭包添加到语言中。

它在语法上可能与Java最相似,没有提供Clojure和Scala提供的一些更丰富的函数构造,但仍然提供了明显的演进改进-特别是用于编写脚本式程序。

在这三种语言中,Groovy拥有最强大的商业支持,主要是通过springsource。

Clojure

Clojure是LISP家族的函数式语言,也是动态类型化的。

像STM支持这样的功能使得它拥有最好的开箱即用并发支持之一,而Scala需要第三方库(如Akka)来复制此效果。

从语法上讲,它也是这三种语言中距离典型的Java代码最远的一种。

我还必须披露,我最熟悉的是Scala :)


11
我之前从未听说过这种名为“Funnel”的语言。感谢你填补了历史记录中的一小部分空白。 - Randall Schulz
8
你不能真正称Clojure为函数式语言。它肯定可以编写命令式代码。 - dbyrne
2
Scala内置了Akka库,用于基于Actor的并发。它不再是第三方依赖项。 - scott m gardner
2
@Orubel 在字节码中,Scala 类与等效的 Java 类是完全相同的-包括类型。例如,整个 Akka Java API 都是用 Scala 编写的。因此,请解释一下你所说的“无法集成”意味着什么-因为这听起来像是FUD(恐吓、不确定性和怀疑)。 - Kevin Wright
3
概括这篇文章:"Scala中的某些特性不能直接在Java中使用"。然而,抽象类型成员和高级类型是相当高级的特性,你并不一定需要使用!同样地,Java也无法使用没有参数、构建器或者Groovy的扩展模块等方法,因此根据您自己的定义,Groovy也"不是紧密集成"。 - Kevin Wright
显示剩余17条评论

68

我从未有时间去学习Clojure。但就Scala和Groovy而言,这是来自Groovy创造者James Strachan的话:

“尽管我的建议是,在长期替代javac方面选择Scala。 我对它印象非常深刻!可以说,如果有人在2003年向我展示了Martin Odersky、Lex Spoon和Bill Venners编写的《Programming in Scala》一书,我可能永远不会创建Groovy。”

您可以在此处阅读整个故事。


72
值得一提的是,这份声明并不是在说Scala比Groovy更好。詹姆斯也因为说过如果他知道创建一门语言有多么麻烦,他就永远不会创造一门语言而闻名。从这个角度来看,很清楚他当时为什么不会开发Groovy。我敢说他提供了许多好点子,但他并不是现在Groovy的创造者。他早在2007年1.0版之前就离开了项目,并且自那以后没有再参与过。在项目中,没有他所贡献的东西和有他所贡献的东西差不多。 - blackdrag
31
考虑到James Strachan正在积极参与Kotlin语言的开发,Scala显然对他来说并不足够引人注目。 - bdkosher
6
他正在研究这个,因为Scala对许多程序员来说太令人印象深刻了...而且更重要的是,在某些地方它太复杂了。 - Display Name

30

它们可以根据它们来自哪里或主要针对哪些开发人员进行区分。

Groovy 类似于 Java 的脚本版本。长期使用 Java 的程序员在构建由大型架构支持的敏捷应用程序时会感到熟悉。 Groovy on Grails 就像其名称所示与 Rails 框架类似。适合那些不想一直被 Java 的冗长代码所困扰的人。

Scala 是一种面向对象和函数式编程语言,Ruby 或 Python 程序员可能更容易接近这种语言。它采用了许多这些编程语言中常见的好思路。

Clojure 是 Lisp 编程语言的一个方言,因此 Lisp、Scheme 或 Haskell 开发者在使用该语言开发时可能会感到熟悉。


24
Scala并不是一个纯函数式编程语言,它首先是一门面向对象的编程语言,但也具备函数式编程特性。 - Daniel C. Sobral
16
我必须说,这个回答感觉很像瞎猜。我认为可以提出一个很好的论点,即Python更接近Groovy而不是Scala,而Ruby(在我看来)与上述任何一种语言都不太接近,可能再次最接近Groovy。Haskell不太像(通用)Lisp或Scheme(因此也不太像Clojure)。对我来说,这个答案感觉(最好的情况下!)就像“我也不知道,让我去维基百科查一下”。 - John Y
21
Scala是一种带有一些函数式特性的命令式语言。如果人们只要语言采用函数式世界中的习惯用法就称之为函数式语言,那么这个术语将成为另一个营销术语。最好开始称C++为函数式语言,Haskell为命令式语言。 - jon hanson
9
@alanlcode Odersky可以说自己想要的。Scala没有任何系统来隔离副作用,它不是默认延迟计算,也不将代码视为数据——而是将_函数调用_视为数据,这是不同的。如果您想完全使用函数式编程,这些都是很大的问题。另一方面,Scala会竭尽全力确保其对象模型没有缺陷。我喜欢Scala,但显然它是次要的函数式。 - Daniel C. Sobral
7
另一方面,ML语言家族被认为是函数式的,但也很严格,并允许副作用/命令式代码。 - GClaramunt
显示剩余10条评论

8
我正在阅读一本由Scott Davis所著、版权为2008年4月出版的实用程序员书籍《Groovy Recipes: Greasing the wheels of Java》。尽管这本书有些过时,但它很清楚地表明了Groovy是Java的扩展。我可以编写与Java完全相同的代码,将文件重命名为*.groovy后,它可以正常运行。根据这本书的说法,如果我包含所需的库,反之亦然。到目前为止,实验似乎证明了这一点。

这是学习Groovy的最佳书籍。 - topr
值得注意的是,并非所有代码都会完全相同。其中一些差异包括Groovy理解单引号和双引号的方式以及其对于装箱优先于扩展的偏好。不过大多数代码仍然能够正常工作。 - Ontonator

4
显然,语法完全不同(Groovy最接近Java),但我想这不是你要问的。如果你有兴趣使用它们来编写Java应用程序脚本,Scala可能不是一个好选择,因为没有简单的方法可以从Java中评估它,而Groovy特别适合这种目的。

我不明白你关于使用Scala来编写Java脚本的观点。你可以编写一个Scala脚本来驱动Java代码,而不需要使用eval。 - Daniel Yankowsky
2
@Daniel,请查看我链接的有关使用Scala进行脚本编写的问题。那里接受的答案是,缺乏“eval”设施和javax.scripting支持使得使用Scala来为Java应用程序编写脚本比使用Groovy更加棘手。 - Thilo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接