在Clojure中定义的目的

时间:2013-07-25 14:42:05

标签: clojure

我对defn的作用感到有些困惑。如果fn只生成匿名函数,我可以理解需要一个结合def和fn功能的构造,但是fn也可以创建命名函数。至少在repl中,我看不出这种用法与defn的区别。

2 个答案:

答案 0 :(得分:6)

当您为fn提供名称符号时,它的仅在函数定义中绑定到函数对象本身。这是为了允许匿名函数调用自己(Clojure - special forms)。

因此,要创建一个绑定到全局可访问名称的fn的函数,必须使用

(def somename 
    (fn ...body...

defn只是一个捷径。

(defn somename 
    ...body...

回复你的评论,来自一个新的代表:

Give me some Clojure:
> (fn foo [] (+ 1 3))
#<sandbox31764$eval31779$foo__31780 sandbox31764$eval31779$foo__31780@12eae8eb>
> (foo)
java.lang.RuntimeException: Unable to resolve symbol: foo in this context
> (defn foo [] (+ 1 3))
#'sandbox31764/foo
> (foo)
4
>  

如您所见,我无法调用foo创建的fn函数,因为它没有绑定到Var。

答案 1 :(得分:1)

主要区别在于defn创建了一个全局名称,而fn只创建一个词法名称。全局名称也是var,因为它最终是使用def创建的。您可以为匿名函数指定的名称不是var,仅在该函数的范围内。这主要是因为函数可以递归。