我的问题的目的是不来开始一场火焰战争,而是确定在什么情况下每种语言都是“这项工作的最佳工具。”
我已经阅读了几本有关Clojure的书籍(Programming Clojure,Practical Clojure,The Joy of Clojure以及Clojure in Action的Manning Early Access版本,我觉得这很棒语言。我目前正在阅读Let Over Lambda,它主要涉及Common Lisp宏,而且它也是一种非常有趣的语言。
我不一个Lisp专家(更像是一个新手),但这个语言系列让我着迷,一般来说功能编程也是如此。
Clojure的优势(以及“他人”的劣势):
在JVM上运行。
JVM是一个非常稳定,高性能的语言环境,非常符合Sun的“一次编写,几乎在任何地方运行”的梦想。我可以在我的Macbook Pro上编写代码,将其编译成可执行的JAR文件,然后在Linux和Microsoft Windows上运行它,只需要进行额外的测试。
(Hotspot和其他)JVM支持高质量的垃圾收集和非常高效的即时编译和优化。就在几年前,我写了一些必须在C中快速运行的东西,现在我毫不犹豫地在Java中这样做。
标准,简单,多线程模型。 Common Lisp是否有标准的多线程包?
使用[]
,{}
和#{}
打破所有这些括号的单调,虽然Common Lisp专家可能会告诉我使用读者宏,你可以添加CL的那些。
Clojure的缺点:
其他人的优点(特别是Common Lisp)(以及Clojure的缺点):
用户可定义的阅读器宏。
其他优势?
思考?其他差异?
答案 0 :(得分:47)
我喜欢Clojure到其他Lisps的个人原因列表(p.s.我仍然认为所有Lisps都很棒!):
在JVM上运行 - 因此可以自动访问JVM本身的精彩工程(高级垃圾收集算法,HotSpot JIT优化等)。
非常好的Java互操作性 - 提供与Java / JVM语言生态系统中大量库的兼容性。我使用Clojure作为“粘合”语言来连接不同的Java库,效果很好。由于我还开发了大量的Java代码,因此Clojure可以很好地与Java工具集成(例如,我使用Maven,Eclipse和Counterclockwise插件用于我的Clojure开发)
矢量[1 2 3]
的合法语法,地图{: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),我个人更喜欢(我认为在函数式语言中将函数和数据保存在同一个命名空间中是有意义的)
答案 1 :(得分:24)
Clojure和Common Lisp之间的一个重要区别是Clojure对函数式编程更具说明性。 Clojure的哲学,习语,以及某种程度上的语言/图书馆强烈鼓励并且有时坚持你以功能性方式编程(没有副作用,没有可变状态)。
Common Lisp肯定支持函数式编程,但它也允许可变状态和命令式编程。
当然,在并发和其他方面,函数式编程有许多好处。但在其他条件相同的情况下,选择您想要针对每种情况使用哪种方法也是很好的。 Clojure并没有完全禁止命令式编程,但它比Common Lisp更不适应这种风格。
答案 2 :(得分:21)
请记住,Clojure是一种语言和实现(通常在JVM上)。 Common Lisp是一种具有十多种不同实现的语言。所以我们这里有一个类别不匹配。例如,您可以将Clojure与SBCL进行比较。
一般而言:
在JVM上运行Common Lisp的一个版本:ABCL
其他大多数Common Lisp实现都没有
大多数CL实现具有多任务处理功能,库提供通用接口
Common Lisp具有数组语法。其他数据类型的语法可以由用户编写,并由各种库提供。
Common Lisp既不支持尾调用优化也不支持continuation。实现提供了TCO,库提供了某种形式的延续。
答案 3 :(得分:10)
这是一段带有comparison of Scheme (Racket mostly) and Clojure的好视频。
公平地说,Racket也有数据类型的语法糖(额外的读者东西)(#hash,#,方括号等)
另外,Clojure进行正确尾调用的唯一方法是使用recur
,这是编译JVM的缺点。
请注意,
recur
是Clojure中唯一不占用非堆栈的循环结构。没有尾调 不鼓励优化和使用自调用来循环未知边界。recur
是 功能及其在尾部位置的使用由编译器验证。 (Special Forms)。