【发布时间】:2013-07-25 14:42:04
【问题描述】:
我对 defn 的作用有点疑惑。如果 fn 只生成匿名函数,我可以理解需要一个结合了 def 和 fn 功能的构造,但 fn 也可以创建命名函数。至少在 repl 中,我看不出这种用法与 defn 有何不同。
【问题讨论】:
标签: clojure
我对 defn 的作用有点疑惑。如果 fn 只生成匿名函数,我可以理解需要一个结合了 def 和 fn 功能的构造,但 fn 也可以创建命名函数。至少在 repl 中,我看不出这种用法与 defn 有何不同。
【问题讨论】:
标签: clojure
当您向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
>
如您所见,我无法调用用fn 创建的foo 函数,因为它没有绑定到Var。
【讨论】:
主要区别在于defn 创建一个全局名称,而fn 只创建一个词法名称。全局名称也是一个 var,因为它最终是用 def 创建的。您可以给匿名函数的名称不是 var,并且仅在该函数的范围内。这主要是因为函数可以递归。
【讨论】: