why clojure?
作者: xumingming | 可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明
网址: http://xumingming.sinaapp.com/294/why-clojure/
网址: http://xumingming.sinaapp.com/294/why-clojure/
本文翻译自: http://clojure.org/rationale 转载请注明出处
一方面客户以及董事们对于工业级别的标准平台如JVM投入了大量的资金,并且对于它的性能,安全性,稳定性都很满意。另一方面java工程师也很羡 慕动态语言的简洁,灵活以及开发效率,他们也希望这些动态语言能运行在客户/董事们所期望的平台上,可以访问那些已经很成熟的java类库,并且性能还应 该不错;他们要用原始的线程、锁来编写多线程程序。clojure就是一个为了满足这些需求的一个尝试: 一个运行在JVM上的动态语言。它可以被使用在java适合的那些场合,它描绘了一个并发编程的前景: 那种到处都是的,没有经过协调的,对资源的并发修改已经过时了。
为了实现clojure的目标:它使用工业级别、开放的平台: JVM;现代化一个传奇性的语言: LISP;使用不可更改的(immutable)的数据结构来进行函数式编程;通过software transactional memory以及asynchronous agents来内在地支持并发编程。其结果就是一个健壮的、实用的、快速的语言clojure的诞生。
why clojure?
为什么我要编写一种新的语言?简单来说,我希望找到一种具有如下特征的语言:
- 它是Lisp的一种方言
- 用它能进行函数式编程
- 它运行在一个已有的、成功的平台上
- 它内置地支持并发编程
但是我发现已有的语言没有一个满足这些条件。下面列举了clojure背后的一些设计动机:
Lisp是个好东西
- 一直被模仿,重未被超越
- lamda表达式使得核心可以很小
- 几乎没有语法
- 核心优势还是代码即数据(code-as-data)以及句法抽象
- 现有的传统Lisp(Common Lisp和Scheme)怎么样呢?
- 在标准化之后几乎没有再改进了
- 核心数据结构可修改,不可扩展
- 语言规范里面没有包括并发编程支持
- JVM上面已经有不错的实现(ABCL, Kawa, SISC)
- 标准Lisp都是用的他们自己的平台
- Clojure是一个不用考虑向后兼容性的Lisp实现
- 把code-as-data的概念扩展到了map和vector
- 数据默认不可修改
- 核心数据结构可以扩展
- 利用已有平台(JVM)
函数式编程是个好东西
- 不可修改数据 + 高阶函数
- 通过约定编程(convention over configuration)上面两点Lisp都可以做到
- 但是如果一个数据是可以修改的,你假定它不会被修改是很危险的
- 在传统Lisp里面,只有list是结构可递归的
- 纯函数式语言一般都会是强静态类型的
- 不是对于每个人,每个任务都合适
- Clojure是一个带有动态特征的函数式语言
- 所有数据结构是不可修改的、持久的并且支持递归
- 多种集合,返回类型
- 动态多态
语言以及平台
- 我说的平台是指虚拟机,而不是操作系统,是未来平台的趋势,它提供:
- 类型系统
- 动态强制以及安全性
- 类库
- 通过抽象使得我们不用关心不同的操作系统
- 一堆现成的工具类
- 内置以及第三方的库
- 内存以及其它资源管理
- 垃圾回收器是平台级别的(JVM),而不是语言级别的(Java)
- 字节码(Bytecode) + 即时编译(JIT compilation)
- 使得我们不用关心硬件
- 类型系统
- 语言作为平台 vs 语言 + 平台
- 旧的方式:每种语言自己建立平台
- GC, bytecode, 类型系统,类库等等
- 新的方式(JVM, .NET)
- 平台和语言是独立的
- 旧的方式:每种语言自己建立平台
- 平台内置的语言 vs 移植到平台上的语言
- 很多新的语言还是走“语言就是平台”的老路
- 当移植的时候就会有“平台到平台”的一些问题
- 内存管理,类型系统,线程问题
- 重复的类库
- 如果这个语言一开始是基于C的话, 一些C的扩展类库可能不好移植过来
- 客户们会认定一些平台
- “必须要运行在JVM/.NET上” VS “必须要运行在Unix/Windows上”
- JVM已经树立了一定品牌
- 现在还开源了
- 与其他语言的互操作
- 同坐C的linkage来做现在已经不是很高效了
- Java/JVM是语言 + 平台
- 一开始设计不是为了这个,但是现在JVM上已经有别的语言了,并且被Oracle接受
- Java是沉闷的、缺乏表达力的
- 没有高阶函数,没有类型推导等等
- 具有调用Java代码的能力是重要的
- Clojure作为语言,JVM作为平台
面向对象被高估了
- 设计的时候是用来仿真的,现在被用在任何地方 — 即使是不恰当的
- 被Java/C#鼓励用在任何地方 — 其实是因为他们除了面向对象也没什么别的东西了
- 可修改状态的对象是新的“臭代码”
- 很难理解,测试
- 对并发编程是个灾难
- 继承并不是实现多态的唯一办法
- “用100个方法来操作一个数据结构比用10方法来操作10个数据结构要好” – Alan J. Perlis
- Clojure把它的数据结构建模成由接口表示的不可变的对象
- 和java的不同就是数据结构很少(seq, map, vector, set),但是每个数据结构的方法很多
- 用java来写java类,在clojure里面使用java的类
多态是个好东西
- 通过switch,if-else“实现的”多态是很脆弱的
- 多态使得我们的系统更可扩展,更灵活
- clojure的multimethods使得多态和面向对象,类型解耦
- 支持多种分类
- 通过静态,动态甚至外部属性,元数据来分派方法(多态)
并发以及多核未来
- 不可更改性可以使得许多并发问题不攻自破
- 对象可以自由的在线程间共享
- 但是对于数据的修改对于仿真来说是必要的
- 锁的机制是很难弄得100%正确的(太难了,我们又太菜)
- Clojure的software transactional memory以及agent系统把所有难点都做掉了(所以我们轻松了)
简单来说,我觉得clojure是JVM上面具有多线程支持的Lisp, 有关它的更多特性看这里。