我的问题的意图是 not 开始一场火焰战,而是确定在什么情况下每种语言都是"the best tool for the job."
我已经阅读了几本有关Clojure的书(Programming Clojure,Practical Clojure,The Joy of Clojure和Manning Early Access版本Clojure in Action),我认为这是一本很棒的语言 . 我目前正在阅读Let Over Lambda,它主要涉及Common Lisp宏,而且它也是一种非常有趣的语言 .
我是一个Lisp专家(更多的是新手),但这个语言系列对我来说很有吸引力,一般来说,功能编程也是如此 .
Advantages of Clojure (以及"others"的缺点):
-
在JVM上运行 .
-
JVM是一个非常稳定,高性能的语言环境,很好地满足了Sun的“一次编写,几乎在任何地方运行”的梦想 . 我可以在我的Macbook Pro上编写代码,将其编译成可执行的JAR文件,然后在Linux和Microsoft Windows上运行它,几乎不需要额外的测试 .
-
(Hotspot和其他)JVM支持高质量的垃圾收集和非常高效的即时编译和优化 . 就在几年前,我写了一些必须在C中快速运行的东西,现在我毫不犹豫地在Java中这样做 .
-
标准,简单,多线程模型 . Common Lisp是否有标准的多线程包?
-
用
[]
,{}
和#{}
打破所有这些括号的单调,虽然Common Lisp专家可能会告诉我,对于读者宏,你可以将它们添加到CL .
Disadvantages of Clojure :
-
在JVM上运行 .
-
没有尾递归或延续 . Common Lisp是否支持延续?我相信,计划需要支持两者 .
Advantages of Others (Common Lisp, in particular) (以及Clojure的缺点):
-
用户可定义的阅读器宏 .
-
其他优势?
思考?其他差异?
4 回答
我喜欢Clojure到其他Lisps的个人原因列表(p.s.我仍然认为所有Lisps都很棒!):
在JVM上运行 - 因此可以自动访问JVM本身的精彩工程(高级垃圾收集算法,HotSpot JIT优化等)
非常好的Java互操作性 - 提供与Java / JVM语言生态系统中大量库的兼容性 . 我使用Clojure作为“粘合”语言来连接不同的Java库,效果很好 . 由于我还开发了大量的Java代码,因此Clojure与Java工具集成得很好(例如我使用Maven,Eclipse和Counterclockwise插件用于我的Clojure开发)
矢量
[1 2 3]
的好语法, Map{:bob 10, :jane 15}
和设置#{"a" "b" "c"}
- 我认为这些非常重要的工具用于现代编程(当然还有列表!)我个人喜欢使用方括号来表示绑定表格:例如
(defn foo [a b] (+ a b))
- 我认为它使代码更清晰易读 .强调使用持久,不可变数据结构的惰性函数式编程 - 特别是所有核心Clojure库都默认支持这一点
用于多核并发的出色STM实现 . 我相信Clojure目前拥有任何语言的最佳并发故事(见video for more elaboration by Rich Hickey himself)
这是一个Lisp-1(比如Scheme),我个人更喜欢(我认为在函数式语言中将函数和数据保存在同一个命名空间中是有意义的)
Clojure和Common Lisp之间的一个重要区别是Clojure对函数式编程更具说明性 . Clojure的哲学,习语,以及某种程度上的语言/图书馆强烈鼓励并且有时坚持你以功能性方式编程(没有副作用,没有可变状态) .
Common Lisp肯定支持函数式编程,但它也允许可变状态和命令式编程 .
当然,在并发和其他方面,函数式编程有许多好处 . 但在其他条件相同的情况下,选择您想要针对每种情况使用哪种方法也是很好的 . Clojure并没有完全禁止命令式编程,但它比Common Lisp更不适应这种风格 .
请记住,Clojure是一种语言和实现(通常在JVM上) . Common Lisp是一种具有十多种不同实现的语言 . 所以我们这里有一个类别不匹配 . 例如,您可以将Clojure与SBCL进行比较 .
通常:
一个版本的Common Lisp运行于JVM:ABCL
大多数其他Common Lisp实现都没有
大多数CL实现具有多任务处理能力,库提供通用接口
Common Lisp具有数组语法 . 其他数据类型的语法可以由用户编写,并由各种库提供 .
Common Lisp既不支持尾调用优化也不支持continuation . 实现提供TCO,库提供某种形式的延续 .
这是一个带有comparison of Scheme (Racket mostly) and Clojure的好视频 .
公平地说,Racket也有数据类型的语法糖(额外的读者东西)(#hash,#,方括号等)
另外,Clojure进行正确尾调用的唯一方法是使用
recur
,这是编译JVM的缺点 .