前言
在lisp程序员看来,form和special form的区别是一目了然而且无需解释的--因为这两个
概念本身就源自lisp.但对于指令式语言的开发人员而言,当他们进入clojure的世界中,会不
断看到和听到这两个名词,然后会把special form理解为某种关键字或者是宏之类的东西.
这样的理解实际上是有一定偏差的.
form
首先让我们来看看Clojure中的form,最简单的form就是由函数和它的参数们构成:
(+ 1 2 3 4)
+是一个函数,后面的1,2,3,4都是这个函数的实际参数.执行这个form的过程是对所有的
参数进行求值,当前情况,对数字求值的结果就是得到数字本身的数值,然后把这些数值作为
参数传递给+函数.
复杂一点的form则是form中的函数以及参数都由其他form构成,比如:
((partial + 5) (* 1 2) (- 3 4))
执行时,会对每一个参数进行求值,第一个位置求值的结果是个用5来和其他参数相加的
函数,第二个位置求值的结果是1和2相乘的值,第三个位置求值的结果是3减去4的值,然后
再对整体form求值,将后两个位置的值作为参数传递给第一个位置得到的函数.
由上我们可以得知,form的组成规则是(函数 若干个参数),form的执行规则是首先对所有
参数求值,然后把若干个参数求值的结果作为实际参数传递给第一个位置求值得到的函数
并执行这个函数得出结果,毫无疑问,这是一个树形的结构,先对分支求值,然后回到主体,对
主体进行求值,最后得出结果.
那么我们来看看special form是怎样的呢.
special form
首先我们看看最简单的special form,变量赋值:
(def a 1)
如果我们用form的方式来进行执行,会发生什么情况呢?
首先,我们会对所有参数求值,def看起来是个库函数,我们先不管它,对参数a求值......等等,
a是个什么东西,它并没有指向任何的值啊.这儿就无法执行下去了,所以,(def a 1)这个东西
并非一个form,而是一个special form.
到此,我们应该能够明白了,special form其实就是不遵从一般form的组成规则和执行规则
的特殊form,它的组成规则和执行规则是由库约定的.像上面的(def a 1)就是指把数值1赋给
变量a,而不是对a和1求值,然后作为参数传递给def.
让我们再看看另外一个special form,条件判断:
(if (= a 1) (println 1) (println 2))
如果我们按照form的方式求值,那么明显地,后面的两个打印函数都会执行;但实际的运行中
只会有一个打印结果,也就代表着只会对某个打印函数求值而不是两个都同时求值,这样也充分
体现了special form和form的不同.