Clojure的学习笔记(一)

由于有过一点点Lisp的基础,所以这个笔记可能并不能完全适应于给别人参考,只是自己学习Clojure的一些笔记。

流控制

Clojure和Lisp类似,都只提供了非常少的流控制语句,从语言设计的初衷来看,函数式语言应该尽量缩短每一个函数的大小,减少复杂的函数内流控制语句。复杂的逻辑应该由函数之间的调用来实现。

if

举例如下:

(defn is-small? [number]
    (if (< number 100) "yes"))

if语句在Lisp中不是函数,因为正常的函数调用都会先对所有的参数求值,之后再调用函数。而if语句的需求(如果条件为真才执行)又不允许对参数先求值,因此在Lisp中if使用宏实现的,Clojure中应该也是。if也支持else配对,不过是隐式的:

(defn is-small? [number]
    (if (< number 100) "yes" "no"))    

这里面“yes”之后的“no”就是else语句。

do

if语句每一个分支仅仅支持一个语句,而如果你是一个复杂的逻辑怎么办?使用do,do会依次对其参数求值,并返回最后一个表达式的值。比如:

(defn is-small? [number] (if (< number 100)
    "yes" 
    (do
        (println "Saw a big number" number) 
        "no" )))

loop/recur

在Clojure中,使用loop和recur来进行循环。Loop和Recur的语法是Lisp中所没有的,因此看起来也很怪异的感觉。Clojure中用recur语句重新绑定loop中绑定的数据,相当于update;而退出loop仅仅是靠其中的if语句。。。

(loop [result [] x 5]
    (if (zero? x)
        result
        (recur (conj result x) (dec x))))

这是一种多么奇怪的表达式啊。但是使用recur可以隐式的创建循环,比如:

(defn countdown [result x]
    (if (?zero x)
        result
        (recur (conj result x) (dec x))))

虽然recur非常有用,但是在Clojure或者Lisp这样的函数式语言中,它是非常少会被用到的,慢慢学习可能就会知道了。

posted @ 2011-10-18 12:10  MMJX  阅读(931)  评论(0编辑  收藏  举报