作者:xiaodan zhuang
链接:https://www.zhihu.com/question/21446061/answer/18421931

1.Clojure能够吸引人的很重要一点是它是JVM之上的语言,这个决定非常关键。
首先,因为根植于JVM之上,并且做到了跟Java语言的相互调用,它能吸引很多成熟的Java开发者。其次,它可以使用Java社区丰富的开源软件,不需要从头去构建一个社区,你可以看到很多Clojure开源代码都是简单地包装Java的开源包,但是通过Clojure高度抽象简单的语法提供更便利的使用的方式;
第三,由于JVM平台本身的高度成熟和优化,clojure的编译器生成的byte code跟Java编译器生成的byte code并无二致(不完全是),它的性能和稳定性也能马上得到保证,这比从头构建一个新平台成本低得多。

构建于JVM之上,Clojure就是一门“严肃”的语言,而非很多人眼中的Lisp“玩具”语言,你学习后可以马上使用并且实践。但是Clojure又是Lisp方言,Lisp的神奇能力它还都保留,这样兼具美学和实用的语言如何让人不爱?我相信很多熟悉Scheme之类方言的童鞋,并且有Java背景的,都会对Clojure有相见恨晚的感觉。

2.Clojure的设计原则可以概括成5个词汇:简单、专注、实用、一致和清晰。这不是我概括的,而是《The joy of clojure》概括的。
(1)简单: 鼓励纯函数,极简的语法(少数special form),个人也认为clojure不能算是多范式的语言(有部分OO特性),为了支持多范式引入的复杂度,我们在C++和Scala身上都看到了。
(2)专注:前缀运算符不需要去考虑优先级,也没有什么菱形继承的问题,动态类型系统(有利有弊),REPL提供的探索式编程方法(告别修改/编译/运行的死循环,所见即所得)。
(3)实用:前面提到,构建在JVM之上,跟Java语言的互操作非常容易。直接调用Java方法,不去发明一套新的调用语法,努力规避Java语言中繁琐的地方(doto,箭头宏等等)。
(4)清晰:纯函数(前面提到),immutable var,immutable数据结构,STM避免锁问题。不可变减少了心智的负担,降低了多线程编程的难度,纯函数也更利于测试和调试。
(5)一致:语法的一致性:例如doseq和for宏类似,都支持destructring,支持相同的guard语句(when,while)。数据结构的一致性:sequence抽象之上的各种高阶函数。

具体到STM,我个人认为这个特性在日常编程中,其实你用到的机会不多。在web编程里,你的并发模型Web Container已经帮你处理(tomcat,jetty),事务也是数据库帮你处理,几乎找不到场合去使用STM。这个特性在做一些中间件或者底层framework的时候才可能用到。这个特性的设计上面已经提到,跟clojure的设计目标是紧密相关的,跟immutable数据结构也是密不可分,同时它也不是没有代价,事务历史记录和慢事务频繁回滚的代价,有时候你还是需要退回去使用Java那套锁机制,庆幸的是Clojure不阻止你去使用,并且提供了类似locking这样的宏来方便你使用。

3.Scheme我对它的了解也就是做过SICP的习题,粗粗看过《Programming Scheme》,两者对比的优缺点似乎谈不上来。需要对Scheme更熟悉的专家来做个对比。

Clojure的设计缺陷不能说是缺陷,这是由于它设计的目标决定的,有得必有失。

首先还是JVM,基于JVM有种种好处,但是JVM的启动速度实在悲剧,因此用Clojure写一些小的script处理日常事务,显得还是不够得心应手,这样的工作我还是用Ruby,Python的脚本语言来搞定更便捷。不过目前Clojure有一些其他语言之上的实现,比如rouge-lang/rouge · GitHub 和 halgari/clojure-py 路 GitHub 这些实现应该会比JVM的启动快很多(抱歉,我没测试过)。

不仅如此,因为Clojure跟JVM平台的绑定如此之深,并且为了真正发挥Clojure的威力,你还需要去熟悉Java平台的东西,熟悉Java语言、类库、内存模型、GC优化、多线程和网络编程、开源类库等等。可以这样认为:想成为一个好的Clojure程序员,首先需要是一名好的Java程序员。这也一定程度上阻碍了Clojure的推广,提高了学习成本。

其次,Clojure的API设计上,有时候不符合你的直觉,而是符合Clojure的哲学,比如contains?函数对vector等数组型集合的调用上。关于这一点,Rich的回答是“Elegance and familiarity are orthogonal.”,也就是优雅和熟悉是正交关系的。保持API内在的一致性,比直觉的“熟悉”更重要。Clojure不妥协于你的“直觉”。

第三,弱类型的好处足够多,灵活,减少声明代码,适合探索式编程;同样,坏处也不是没有,没有类型保障,错误可能要等到运行时才能发现,静态代码检查工具也没有办法帮你发现,这就需要你一定程度的测试代码来保证运行时行为。

第四,性能上,虽然clojure生成的字节码已经很高效,也有type hint这样的技术来帮助提升性能,但是会有不少的转型(checkcast)、装箱和拆箱(boxing and unboxing)以及类型判断分支跳转的多余指令,这在一些性能敏感的应用里可能会暴露出来。尽管我认为大多数网站型的应用瓶颈都会落在IO上。

以上是我对这个问题的一些看法,欢迎探讨。谢谢。

P.S. 我们的整个网站几乎都是基于 clojure 架构的,有兴趣可以看下 AVOS Cloud,每天承载的请求量也在亿次级别。

 
 

Elegance and familiarity are orthogonal.的更多相关文章

  1. Clojure 哲学

    简单性.专心编程不受打扰(freedom to focus).给力(empowerment).一致性和明确性:Closure编程语言中几乎每一个元素的设计思想都是为了促成这些目标的实现. 学习一门新的 ...

  2. Orthogonal Least Squares Learning Algorithm for Radial Basis Function Networks

    Orthogonal Least Squares Learning Algorithm for Radial Basis Function Networks S. Chen, C. F. N. Cow ...

  3. ODC(Orthogonal Defect Classification)简介——正交缺陷分类法

    Defect分析是软件开发和测试中一个重要的环节,ODC介绍了一种不同于大家常用的非常有效的defect分类及分析方法.这篇文章简单的向大家介绍了什么是ODC,以及如何在项目和产品开发中使用ODC来改 ...

  4. 【线性代数】4-4:正交基和Gram算法(Orthogonal Bases and Gram-Schmidt)

    title: [线性代数]4-4:正交基和Gram算法(Orthogonal Bases and Gram-Schmidt) categories: Mathematic Linear Algebra ...

  5. Orthogonal Convolutional Neural Networks

    目录 概 主要内容 符号说明 的俩种表示 kernel orthogonal regularization orthogonal convolution Wang J, Chen Y, Chakrab ...

  6. 正交函数(orthogonal functions)

    a map is a function. 映射即函数: 1. 双线性映射与双线性形式 bilinear map 基于同一定义域,将两个向量空间(V,W)中的向量映射为第三个向量空间(X)的向量的函数: ...

  7. 正交矩阵(Orthogonal Matrix)

  8. Getting started with new I/O (NIO)--reference

    The new input/output (NIO) library, introduced with JDK 1.4, provides high-speed, block-oriented I/O ...

  9. ROC 曲线/准确率、覆盖率(召回)、命中率、Specificity(负例的覆盖率)

      欢迎关注博主主页,学习python视频资源 sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频教程) https://study.163.com/course/introduction.ht ...

随机推荐

  1. 飞思卡尔单片机P&E开发工具硬件及软件

    原文链接: http://blog.sina.com.cn/s/blog_8ebff8d7010121tm.html 1.HC(S)08系列 开发机硬件:USB-ML-12 CYCLONE PRO U ...

  2. 时间序列分解算法:STL

    1. 详解 STL (Seasonal-Trend decomposition procedure based on Loess) [1] 为时序分解中一种常见的算法,基于LOESS将某时刻的数据\( ...

  3. python3 利用正则获取网页中的想保存下来的内容

    需要获取某个网页中表格部分中某个产品的成份 分析在html中成份的元素代码 <a href="/composition/4c3060178d1184935a48c4e51be4f63f ...

  4. 初尝 nginx

    第一次尝试用 nginx,记录下几个简单命令: // 启动 start nginx // 测试并设置配置文件 nginx -t -c conf\nginx.conf // 修改配置文件后重载 ngin ...

  5. JavaWeb开发环境配置

    JavaWeb开发环境配置(win7_64bit) 目录 1.概述 2.JavaWeb学习路线 3.JavaWeb常用开发环境搭建 4.注意事项 >>看不清的图片可在新标签打开查看大图 1 ...

  6. Navicat(数据库可视化操作软件)安装、配置、测试

    Navicat(数据库可视化操作软件)安装.配置.测试(win7_64bit) 目录 1.概述 2.本文用到的工具 3.Navicat安装.激活与配置 4.简单测试 5.注意事项 6.相关博文 > ...

  7. SQL2008R2的 遍历所有表更新统计信息 和 索引重建

    [2.以下是更新统计信息] DECLARE UpdateStatisticsTables CURSOR READ_ONLY FOR SELECT sst.name, Schema_name(sst.s ...

  8. 如何免费的将本地Web服务映射到外网

    链接地址:https://hongmaju.github.io/2018/05/13/ngrok%E5%B0%86%E6%9C%AC%E5%9C%B0Web%E6%9C%8D%E5%8A%A1%E6% ...

  9. jquery $('#form1').serialize()序列化提交表单

    1.$("#form1").serialize() 把form表单的值序列化成一个字符串,如username=admin&password=admin123 <for ...

  10. 【iCore4 双核心板_ARM】例程三十四:U_DISK_IAP_ARM实验——更新升级STM32

    实验现象及操作说明: 1.本例程共有两个代码包,APP和IAP,IAP程序功能实现将APP程序升级至STM32中. 2.直接上电或烧写程序将执行升级的APP应用程序. 3.按下按键上电或写程序将进行升 ...