Clojure 语言的设计

基于 JVM 的决定程序员

Clojure 可以吸引人的很重要一点是它是 JVM 之上的语言,这个决定很是关键。web

  • 首先,由于根植于 JVM 之上,而且作到了跟 Java 语言的相互调用,它能吸引不少成熟的 Java 开发者。
  • 其次,它可使用 Java 社区丰富的开源软件,不须要从头去构建一个社区,你能够看到不少 Clojure 开源代码都是简单地包装 Java
    的开源包,可是经过 Clojure 高度抽象简单的语法提供更便利的使用的方式;
  • 第三,因为 JVM 平台自己的高度成熟和优化,clojure 的编译器生成的 byte code 跟 Java 编译器生成的 byte
    code 并没有二致(不彻底是),它的性能和稳定性也能立刻获得保证,这比从头构建一个新平台成本低得多。

构建于 JVM 之上,Clojure 就是一门 严肃 的语言,而非不少人眼中的 LISP 家族中的 玩具 语言,你学习后能够立刻使用而且实践。可是 Clojure 又是 LISP 方言,LISP 的神奇能力它还都保留,这样兼具美学和实用的语言如何让人不爱?我相信不少熟悉 Scheme 之类方言的童鞋,而且有 Java 背景的,都会对 Clojure 有相见恨晚的感受。数据库

设计原则编程

Clojure 的设计原则能够归纳成 5 个词汇:简单、专一、实用、一致和清晰。这不是我归纳的,而是《The joy of clojure》归纳的。数组

  • 简单 : 鼓励纯函数,极简的语法(少数 special form),我的也认为 clojure 不能算是多范式的语言(有部分 OO
    特性),为了支持多范式引入的复杂度,咱们在 C++ 和 Scala 身上都看到了。
  • 专一 :前缀运算符不须要去考虑优先级,也没有什么菱形继承的问题,动态类型系统(有利有弊),REPL 提供的探索式编程方法(告别修改 /
    编译 / 运行的死循环,所见即所得)。
  • 实用 :前面提到,构建在 JVM 之上,跟 Java 语言的互操做很是容易。直接调用 Java 方法,不去发明一套新的调用语法,努力规避
    Java 语言中繁琐的地方 (doto, 箭头宏等等)。
  • 清晰:纯函数(前面提到),immutable var,immutable 数据结构,STM
    避免锁问题。不可变减小了心智的负担,下降了多线程编程的难度,纯函数也更利于测试和调试。
  • 一致 :语法的一致性:例如 doseq 和 for 宏相似,都支持 destructring, 支持相同的 guard
    语句(when,while)。数据结构的一致性:sequence 抽象之上的各类高阶函数。
  • 具体到 STM,我我的认为这个特性在平常编程中,其实你用到的机会很少。在 web 编程里,你的并发模型 Web Container
    已经帮你处理(tomcat,jetty),事务也是数据库帮你处理,几乎找不到场合去使用 STM。这个特性在作一些中间件或者底层
    framework 的时候才可能用到。这个特性的设计上面已经提到,跟 clojure 的设计目标是紧密相关的,跟 immutable
    数据结构也是密不可分,同时它也不是没有代价,事务历史记录和慢事务频繁回滚的代价,有时候你仍是须要退回去使用 Java 那套锁机制,庆幸的是 Clojure 不阻止你去使用,而且提供了相似 locking 这样的宏来方便你使用。

缺陷tomcat

Clojure 的设计缺陷不能说是缺陷,这是因为它设计的目标决定的,有得必有失。网络

  • 首先仍是 JVM,基于 JVM 有种种好处,可是 JVM 的启动速度实在悲剧,所以用 Clojure 写一些小的 script
    处理平常事务,显得仍是不够驾轻就熟,这样的工做我仍是用 Ruby,Python 的脚本语言来搞定更便捷。不过目前 Clojure
    有一些其余语言之上的实现,好比 clojure-py、joxa、clojureclr 这些实现应该会比 JVM
    的启动快不少(抱歉,我没测试过)。 不只如此,由于 Clojure 跟 JVM 平台的绑定如此之深,而且为了真正发挥 Clojure
    的威力,你还须要去熟悉 Java 平台的东西,熟悉 Java 语言、类库、内存模型、GC
    优化、多线程和网络编程、开源类库等等。能够这样认为:想成为一个好的 Clojure 程序员,首先须要是一名好的 Java
    程序员。这也必定程度上阻碍了 Clojure 的推广,提升了学习成本。
  • 其次,Clojure 的 API 设计上,有时候不符合你的直觉,而是符合 Clojure 的哲学,好比 contains? 函数对
    vector 等数组型集合的调用上。关于这一点,Rich 的回答是 Elegance and familiarity are
    orthogonal.,也就是优雅和熟悉是正交关系的。保持 API 内在的一致性,比直觉的 熟悉 更重要,这是更深刻思考、理性的直觉。
  • 第三,弱类型的好处足够多,灵活,减小声明代码,适合探索式编程;一样,坏处也不是没有,没有类型保障,错误可能要等到运行时才能发现,静态代码检查工具也没有办法帮你发现,这就须要你必定程度的测试代码来保证运行时行为。
  • 第四,性能上,虽然 clojure 生成的字节码已经很高效,也有 type hint 这样的技术来帮助提高性能,可是会有很多的转型
    (checkcast)、装箱和拆箱(boxing and
    unboxing)以及类型判断分支跳转的多余指令,这在一些性能敏感的应用里可能会暴露出来。尽管我认为大多数网站型的应用瓶颈都会落在 IO
    上。

总之, Clojure 是一门精心设计的、彻底融入做者对编程的思考的、富有生产力的现代编程语言,值得每一个对生产效率、函数式编程、并发编程有兴趣的朋友深刻了解下。数据结构

相关文章
相关标签/搜索