Clojure 给 JVM 带来了 STM、LISP

阅读数:2477 2009 年 2 月 1 日

话题:JavaRuby编程语言架构语言 & 开发

Clojure是 Lisp 语言家庭中的新近成员,运行于 Java 平台之上。它于 2007 年面世,并已获得了广泛关注。原因之一在于 Clojure 解决并发问题的方法是建立于软件事务性内存(STM)之上的。

Stuart Halloway《Programming Clojure》(由 Pragmatic Programmers 出版社出版)一书的作者,该书目前尚处于 beta 版阶段。我们和 Stuart 就 Clojure、STM、工具等内容进行了交谈。

InfoQ:Clojure 使用STM来实现并发;你能对 STM 进行一番简明扼要的介绍吗?

STM 是一个更大故事的一部分:针对可变状态的明确 API(explicit APIs for mutable state)。通过将代码分成纯函数层和可变层,你可以得到 2 个极大的好处:

* 你的纯函数代码更容易测试和重用

* 你可以选择符合你的并发性和伸缩性需要的明确可变 API(explicit mutable API)。Clojure 为不同状况提供了 4 种不同的 API:refs 和 STM、agents、vars 和 atoms。此外,你总能向下再深入一层,使用 Java 并发 API。

InfoQ:另一类对 Clojure 感兴趣的是已经熟悉 Lisp 的程序员;在尝试使用 Clojure 时,他们有什么需要注意的?

我对 Lisp 使用者的建议是“一开始要有耐心。”Clojure 是自由的 Lisp,不存在和其他 Lisp 向后兼容的问题。这意味着在实际过程中有很多东西是不同的。一旦你在 Clojure 上花了些时间,你可能就会同意 Rich 的设计决策,认为其动机是非常不错的。

Clojure 网站已经有了一份文档来说明它和很多其他 Lisp 的区别。Clojure 的创造者 Rich Hickey 提供了一些幻灯片(PDF 链接)来向 Java 开发者讲解 Clojure,以及反过来从 Lisp 使用者的角度来讲解 Clojure

InfoQ:对于 Java 使用者,或更普遍的,使用 OOP 的开发者来说,有什么习惯是他们在使用 Clojure 时需要抛弃的?

不象其他新的 VM 热门语言,Clojure* 不是 * 面向对象的。这一开始可能会把人给吓住:“没有对象,我该怎么来设计一个系统?”

但是 Clojure* 的确 * 提供了很多你想从 OO 中得到的东西:

* 封装(通过名字空间、私有定义和闭包)

* 强大的多态(multimethods)

* 函数重用比继承更胜一筹。(函数和不可变状态组合比继承层次更优。)

Clojure 和众多 OO 语言的区别在于:OO 语言提供的是套餐,选择有限;而 Clojure 提供的则是散餐,可照单随意选择。

InfoQ:对于 Lisp 的初学者,你有什么资源可推荐的(当然,除了你的书之外)?

Clojure 和很多好思想联系紧密。除了《Programming Clojure》之外,我会推荐

* Seibel 的《Practical Common Lisp》很适合想尽快提高 Lisp 的人

* Graham 的《On Lisp》有助于了解 Lisp 的宏

* Goetz 等人所写的《Java Concurrency in Practice》讨论了并发性

* O'Sullivan 等人所写的《Real World Haskell》可帮助了解函数编程

* Abelson 和 Sussman 的《Structure and Interpretation of Computer Programs》,因为每个人都应该读一读它

附注:这些书大多数同时还是可在线免费获得的:《Practical Common Lisp》《On Lisp》《Real World Haskell》《SICP》

InfoQ:Clojure 开发者应该避免哪些旧的 Lisp 模式 / 实践?(如,不要到处都使用 list,取而代之尽量优先使用 Clojure 的数据结构,如 maps、vectors 等?)。

你真是说到了这个问题的点子上。在 Clojure 中,list 主要是用于代码。至于数据,则要根据不同情况选择合适的结构,拥抱 sequences 库。不要害怕直接调用 Java API。

InfoQ:Clojure 的库生态系统怎样?

对于任一已知需求(Web 开发、数据库存取、测试、BDD)都有 3 到 4 个即将面世的 Clojure 库。这本书中“Clojure in the Wild”一章对它们进行了简要的介绍,并进一步提供了使用 test-is 测试框架和 Compojure 的例子。

在 Clojure 的邮件列表中,Rich Hickey 最近要求 Clojure 库的维护者报告他们正在开发的库。在GitHub 中的 Clojure 语言分类下可找到大量的 Clojure 项目。

InfoQ:你愿意看到一个多平台的 Clojure(不只是针对于 Java 平台的 Clojure)出现吗?

不愿意。Clojure 和 Java 的紧密集成是其动力的关键。当然,我很高兴看到与.NET 平台有关的实用 Lisp——但它不应该是 Clojure。

InfoQ:你使用什么工具来进行 Clojure 编程?

我使用 Emacs,偶尔再加上 SLIME。但我已经是一名 Emacs 使用者了,因而上述选择显而易见。另外,还存在针对于 vi、Eclipse、IDEA 和 NetBeans 的插件。

支持 Clojure 的一些 IDE/ 编辑器的例子是:clojure-dev(Eclipse)、clojure-intellij-plugin(IntelliJ)、enclojure(NetBeans)。Gorilla(VIM),它类似SLIME(Emacs)(Bill Clementson 已经写了一篇在 Emacs 和 SLIME 中配置 Clojure 环境的指南)

由于很多这些工具都需要完成类似的工作,已经出现了关于在这些工具的一个公共后台之上进行合作的呼声。一种选择是采用类似 SLIME 和 Gorilla 的做法,即运行一个 Clojure 实例,然后通过查询它来完成文档查看(Clojure 符号将它们的文档字符串作为元数据携带),代码查看、名字空间浏览等工作。

InfoQ:你现在会在复杂的商业项目中使用 Clojure 吗?

如果身处一个敏捷团队,有好的测试套件,我目前会毫不犹豫的将 Clojure 用于产品环境之中。

InfoQ 最近报道了一个将 Clojure 应用投入生产环境的例子。(InfoQ 上更多关于 Clojure 的内容)。

你会考虑 Clojure 吗?Clojure 的哪方面最让你感兴趣——它的 Lisp 血统、STM 或其他?

查看英文原文Clojure Brings STM, LISP to the JVM