先说一些共同点:
都试图利用成熟的 JVM,并可以使用 JVM 平台上现存的代码和广泛的库,同时避免 Java 语言表达上的一些弱点。两者都试图将函数编程 (FP) 引入到原本是为纯 OO 语言 Java 定制的 JVM 上。因此,它们都具有 FP 的特征:函数是头等公民,可以作为参数传递,可以作为返回值返回。但两种语言的设计哲学截然不同:
Clojure 是历史悠久的 Lisp 的一种方言,它需要尊重 Lisp 的传统:包括臭名昭著(对 Lisp 爱好者是香味扑鼻)的括号海洋。当然 Clojure 做了很多不同传统 Lisp 的处理,如引入了 Vector,map 等基本类型,而不只是 List。而 Scala 是全新设计的语法,它不受过往语法的限制;它深受 Haskell 的影响,有抽象数据类型 ADT、 模式匹配等鲜明特征。Scala 是强类型语言,编译器积极检查数据类型,有类型推断等新类型语言的先进特征。Clojure 是鸭子类型语言,编译器不检查类型,这责任在于程序员自己(目前 core.typed 库试图把强类型检查作为可选项加入到 Clojure 语言中,不过还远远不到成熟的地步)。Scala 认为 OO 和 FP 都是非常有效的表达方法,因此在语言中同时支持它们。Clojure 则强烈不鼓励使用 OO 编程,尽管从与 Java 互通等方面出发有一些支持。它强烈倾向于 FP 编程。带来的后果是 Scala 的程序风格可能会非常多样,而 Clojure 则相对统一。Scala 是传统的语言开发方式:有相当多的关键字和语法糖,都需要核心开发者支持。虽然加入了元编程能力,但其元编程与普通编程区别很大,难以被一般开发者使用。 Clojure 从 Lisp 处继承的代码即数据的核心,则保证了极为自然和强大的元编程能力,任何开发者都很容易用宏来定义自己的语法,因此基于 Clojure 定义自己的领域语言(DSL)非常容易。由于其多样的语法特点,多种语义的支持,Scala 是一种相当复杂的语言,其语法的数量比 Java 语言还要多,更不要说其独立于 Java 的自己的类型系统。与之相对,Clojure 的内核非常简单,语法极为简化。一个重要的后果是,Clojure 成熟较快,编译器本身容易开发,而 Scala 的编译器开发难度大得多。我本人是在评估了两种语言的稳定性后做出的选择。两种语言都是通用性的,因此是互相竞争关系,都声称自己适合全领域的编程。虽说在具体的库支持上可能互有长短(比如 Clojure 的 STM 被认为是更容易进行并行编程,而 akka 这样的 actor 库可以让 Scala 具有 Erlang 一般的能力),但这些很可能是临时的。所以考虑到选择一种新的语言,特别是如此有特点的两种语言,需要做好颠覆三观的准备(特别是少接触 Lisp 的大多数程序员),然后根据自己的喜好进行选择。
PS. 有人提出 Clojure 的可读性不好,这点我非常不同意。这很可能是熟悉程度弱所带来的一种偏见。对于自己不熟悉的语法表达会有这种看法。实际上,由于 Clojure 的语法统一程度强,一般来说好的 Clojure 程序的一致性会更好。当然,你也可以用它写出很烂的完全不可读的程序,但哪种语言也无法避免这样的可能吧?
PPS. FP 与 OO 的编程逻辑截然不同,从 OO 为主转为 FP 需要大的习惯转变。但如果不进行这种转变,何必学习一种新的语言来表达呢?特别是 Java 8 也已经加入了相当的 FP 支持,可以在 OO 为主的环境中加入 FP 的味道了。另外,Clojure 并不是纯粹的 FP 语言,从实用性的角度上它支持相当多的可变性编程;更纯粹的 FP 语言是 Haskell,学院派(非爱好者的“不实用”的说法)的语言。