我是Clojure的新手,并且正在抓紧理解这些概念。 REPL有助于我获得" stuff"的文档。所以我想定义一个函数......
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 clojure_noob.core$eval3364$add_pair__3365@6fb5a33b>
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>
离开这个名字并建立一个正确的fn 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特殊形式。感谢。
答案 0 :(得分:4)
从REPL调用(fn add-pair [a b] (+ a b))
构建该函数的实例,然后将其打印到屏幕上。之后它会消失,不会保存在任何地方。这就是为什么你不能使用doc
函数获取它的文档。 fn
文字中的name参数通常用于进行递归调用,并不意味着它将在任何地方通过该名称保存。
如果你拨打(defn add-pair [a b] (+ a b))
,那么将该功能保存到命名空间,然后doc
功能可以在以后查找并打印它的文档字符串。
答案 1 :(得分: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
如果您希望全局访问该功能,请将其绑定到
var
使用def
:
(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