为啥选Clojure? --- Robert C. Martin

为啥选Clojure?

       Why Clojure? --- by Robert C. Martin (Uncle Bob) 2019/8/22

       原blog链接:http://blog.cleancoder.com/uncle-bob/2019/08/22/WhyClojure.html

       主题:Clojure是最经济的编程语言

 

从汇编到Java,我用过很多语言编写系统。用过二进制机器语言写程序。用过Fortran、COBOL、PL/1、Pascal、C++、Java、Lua、Smalltalk、Logo、还有一打其他语言开发应用。用过静态类型语言。用过无类型语言。用过动态类型语言。用过Forth这种基于栈的语言,用过Prolog这种基于逻辑的语言。

 

在过去50年里,我使用过很多不同的编程语言。

 

所以我得出一个结论:

 

在这些语言中,我喜欢就是它,它的存活期将超过其他所有语言,它将会变成所有程序员都会使用的标准语言,它就是Lisp。

 

这个结论不是我随意给出来的,我甚至不愿意给出这个结论。我不是Lisp的粉丝。我见到CARs、CDRs、CADDADDRs这些学院派的相关报告,内容有趣但是不实用。十年前我发现SICP,然后又找到Clojure。Clojure是基于Java生态圈上实现的Lisp语言(不涉及CARs、CDRs、CADDADDRs)。

 

我也是花了好几年才意识的。经过了一些磕磕绊绊或挫折之后,我开始意识到这个是我用过的最简单、最优雅、强制性最少的语言。

至于具体原因列表如下,开始吧。

 

1、表达的经济性

 

这是全部的原因,也是唯一的原因。用Clojure写代码时,代码更简洁、更容易、更流畅、更少行数、更少字符、更少脑细胞。

 

其实原因很简单,Clojure几乎没有句法或语法。再重复一遍:

Clojure几乎没有句法或语法!

 

下面用样例代码直观展示出来看看,程序要求:打印1~25个整数的平方值。

(println (take 25 (map #(* % %) (range))))

主要语法如下:

  • ( 开始
  • ) 结束
  • names 直接命名,这个例子里就是命名就是方法
  • * 乘法
  • # 后面代码解释做为方法
  • % 方法的参数位置

 

上面样例基本上包含了Clojure 80%的语法,让我们捋一遍样例代码。

(println (take 25 (map #(* % %) (range))))

Clojure解释list就是直接调用方法小括号()。本样例中的这个方法就是println,等同于Java中System.out.println。我们讲take执行结果传给println。

take方法有两个参数,第一个参数是25,第二个参数是list。这里的take方法执行结果会返回1~25个结果。

map方法有两个参数,第一个参数是方法体,第二个参数是list。

 

map方法中的第一个参数是个方法,是用#号匿名创建的方法,调用内容为第一个参数%乘以第一个参数%。

map方法中的第二个参数是list,调用range方法返回的list。range方法直接返回非负的整数list。(这个list用lazy方式延迟加载)。

 

我们也可以用定义方法来替换%的语法,例如创建square方法:

(defn square [x] (* x x)) (println (take 25 (map square (range))))

defn方法定义方法square,这里的中括号[]跟java里的小括号()作用是一样的。 map方法就可以执行square了。

到这里你已经见识到Clojure 90%的语法了。下面是一段同样效果的Java代码:

public class SquaresOfIntegers { public static void main(String[] args) { for (int i=0; i<25; i++) System.out.println(i*i); } }

对比就能看出Java代码的庸长(加上类名的定义更长),经过各层级的对比筛选,Clojure在语法上是最精简的。精简的语法意味着可以清晰地、直接地、更少歧义的代码表达。

 

我是一名C++程序员,以前还是C++语言的顾问,我之前着迷于重语法的语言。二十年前我过渡到了Java。Java算是瘦身版的C++。这次过渡到Clojure令人大开眼界。这种轻量化语法的语言,我以前以为适合给学校的学生做练习时用,不适用于构建大型系统。在我印象里,大系统等同于重语法,看来是我错了。我发现用轻量级语法的Clojure更有利于构建大系统。构建大系统时Clojure更简洁、更容易这点毋庸置疑。

 

关于....?

看到这里,你可能会有问题或疑惑,我试着回复一些。

 

天那,怎么全是括号

Java的方法调用:f(x),Clojure的方法调用:(f x),这里没有多余的括号。有些人也能减少括号的使用,不过是要通过使用内嵌函数的方式。看看上面的整数求平方square的代码,如果你不喜欢这种内嵌的语法,你可以接着使用线程宏。

它会很慢吗?

Clojure不慢,它不是C也不是汇编。不过不要指望快到纳秒级别,这个级别Java和C#也做不到。如今99.9%的软件都不需要这个级别的性能。我用Clojure创建过一个实时的、基于GUI、有动画效果的游戏(space war),速度表现的还不错。

关于Javascript?

ClojureScript可以将Clojure编写好的程序直接编译为Javascript,并且可以在浏览器里很好的运行。我上面提及到space war游戏程序就是用ClojureScript编译的,比默认帧数更高设置的浏览器里运行正常。

它是动态类型!

你尝试去写下测试程序,这部分你可以使用clojure/spec库,并指定你类型的schema,在代码前后做动态类型检查,你会有惊喜的。

它是动态类型!!

声明类型需要语法,语法会降低表达的经济性。

它是动态类型!!!

好吧,我知道你静态类型,你能很好的运用静态类型。不过别人完成工作在外游玩的时候,你可能还在coding。

 

关于IDE?

IntelliJ安装Cursive插件就可以搞定开发环境了,不过大部分程序员用的是Emacs。

 

关于重构?

IntelliJ用Cursive就可以进行一些很好的重构了,尽管他们不使用“Extract Method”。

 

关于跟Java的交互?

Clojure程序可以直接调用Java,Java程序通过一些设置也可以调用Clojure,不用担心他们俩之间的交互问题。bb

在哪里能找到Clojure程序员?

(They’re out there; but you are better off making them. The syntax is trivial. The Java platform you likely already know. Just decide to build your next system in Clojure. Spend a week or two getting used to the language. Then start. Oh, by the time you’re a couple of months in you’ll realize how primitive your early stuff was, and you’ll be tempted to clean it up. But what else is new?)

关于新语言?

新语言层出不穷,我们不缺新语言。不过这些新出来的语言都没有什么新的创见,仅仅是在一些原有的语言上做了些修修补补。这么说不完全正常,这里面还是有不少好点子的。但都不是变革。不过Clojure做到了。我没有发现任何新语言几乎与Clojure一样引人注目,仅仅因为几乎所有语言都具有额外的语法。

其他语言也有精简的语法,但为什么不是他们那?

Forth有极小的语法,Smalltalk也是。但是这两各语言都有他们自己的包袱。Forth不是一门流畅的语言,经济性的表达并没有体现在代码里,尽管我也着迷过PostScript。

Smalltalk是短小、优雅和优美的。它引领了设计模式的变革,引领了重构的变革,引领了TDD的变革,帮助引领了Agile的变革,Smalltalk是一门极具冲击力的语言。Smalltalk还是一门基于图像的语言,几乎没有程序员知道这意味着什么,所以很不幸,它被用来作为基于文本文件的语言来对待。

Lisp的历史比Smalltalk和Forth更久远,它创建于1957年。它没有走Smalltalk、Forth的老路。在多次围剿下它没有死掉。像邻家的流浪猫一样继续向家的方向走着。

 

最后,Lisp是实用的,在我看来以后也会很实用。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值