2015-04-01 50 views
0

我是Clojure的新手,并且非常了解这些概念。 REPL帮助我获得“材料”的文档。所以我想定义一个函数...我不明白(doc fn)...它说我可以命名一个函数,但是我不能用它的名字来调用它吗?

clojure-noob.core> (doc fn) 
------------------------- 
clojure.core/fn 
    (fn name? [params*] exprs*) 
    (fn name? ([params*] exprs*) +) 
Special Form 
    ... 
    name => symbol 

...和文档建议我可以命名我的函数。该REPL接受我的功能,但我不能调用它,“无法解析符号。” ...

clojure-noob.core> (fn add-pair [a b] (+ a b)) 
#<core$eval3364$add_pair__3365 [email protected]> 
clojure-noob.core> (add-pair 1 2) 
CompilerException java.lang.RuntimeException: Unable to resolve symbol: add-pair in this context, compiling:(/private/var/folders/1g/fnytl2x93sx6hp2f1rsf4h1r5xtqv_/T/form-init6828995349142227131.clj:1:1) 
clojure-noob.core> 

娅的名字和建设的新生力量适当DEF并完成这项工作作为确实撬动DEFN宏观的事情...

clojure-noob.core> (def another-add-pair (fn [a b] (+ a b))) 
clojure-noob.core> (another-add-pair 1 2) 
3 
clojure-noob.core> (defn yet-another-add-pair [a b] (+ a b)) 
#'clojure-noob.core/yet-another-add-pair 
clojure-noob.core> (yet-another-add-pair 3 4) 
7 

显然有一些我不明白有关的(doc fn)输出。特别是,那里的name?是什么,你可以用它做什么?我尽可能多地学习如何阅读文档以及理解fn特殊形式。谢谢。

回答

4

REPL调用(fn add-pair [a b] (+ a b))构建该函数的一个实例,然后将其打印到屏幕上。之后,它消失,不保存在任何地方。这就是为什么你不能使用doc函数得到它的文档。 fn文字中的名称参数通常用于进行递归调用,并不表示它将在任何地方以该名称保存。

如果你调用(defn add-pair [a b] (+ a b))然后保存功能到命名空间,然后doc功能是以后能看它和打印的doc string。

+5

为'名称ARG fn'也被用来制造踪迹更具可读性,并使其更容易识别哪些匿名FN看到错误 – noisesmith 2015-04-01 21:19:25

+0

S /只/常/ ...固定; - ) – 2015-04-01 21:48:39

+0

@noisesmith啊哈!而已。我懂了。 – 2015-04-01 21:49:31

2
  • fn形式的计算结果为函数对象

  • 您可以立即应用函数对象:

    ((fn [a b] (+ a b)) 1 1) ;=> 2

  • 如果你想引用函数对象在本地,使用let 结合:

    (let [add-pair (fn [a b] (+ a b))] (add-pair 1 1)) ;=> 2

  • 功能对象与1[3 :a]

    (let [double (fn [n] (* 2 n))] (({double (comp double double)} double) 3) ;=> 12

  • let结合fn形式中不存在的 - 你需要一个 名称参数:

    ((fn fact [n] (case n, 0 1, (* n (fact (dec n))))) 5) ;=> 120

  • letfn做两件事:

    (letfn [(fact [n] (case n, 0 1, (* n (fact (dec n)))))] (fact 5)) ;=> 120

  • 如果你想要的功能全局访问,使用def其绑定到 var

    (def fact (fn fact [n] (case n, 0 1, (* n (fact (dec n))))))

    (fact 5) ;=> 120

  • defn宏做了同样的更简洁:

    (defn fact [n] (case n, 0 1, (* n (fact (dec n)))))

    (fact 5) ;=> 120

相关问题