第一个例子:
(def fifth (comp first rest rest rest rest))
(fifth [1 2 3 4 5])
;=> e
第二个例子:
(defn fnth [n]
(apply comp
(cons first
(take (dec n) (repeat rest)))))
((fnth 5) '[a b c d e])
;=> e
为什么在第二个例子中(但不是在第一个例子中)我需要一个撇号?没有第二个例子会引发错误。
答案 0 :(得分:8)
在第二个例子中,你必须使用撇号,因为你想要阻止评估向量的元素。如果删除撇号,Clojure将尝试解析符号a
,b
等,就像它们绑定某些值一样。
示例:
user> '[a b c d e]
;; => [a b c d e]
user> [a b c d e]
CompilerException java.lang.RuntimeException: Unable to resolve symbol: a
user> (let [a 1
b 2
c 3
d 4
e 5]
[a b c d e])
;; => [1 2 3 4 5]
请注意,您不必对数字使用aphostrophe,因为他们会评估自己:
user> 1
;; => 1
user> 2
;; => 2
user> [1 2 3]
;; => [1 2 3]
虽然符号没有,但Clojure将搜索给定符号绑定的值:
user> x
CompilerException java.lang.RuntimeException: Unable to resolve symbol: x
因此,在进入函数之前,了解此信息以及函数的参数被评估的事实,应该清楚为什么以及何时在向量之前使用撇号。
答案 1 :(得分:2)
在第二个例子中,引用'
是为了防止评估者评估它后面的形式(向量)。
其中的符号不进行自我评估(请在此处阅读http://clojure.org/evaluation),评估人员会尝试解决这些问题。
电子。 G。
(def foo 42)
[foo]
=> [42] ;; vector with number 42, resolved via foo
'[foo]
=> [foo] ;; vector with the symbol foo, decoupled from the var foo
您可能希望在此处阅读另一个quote
示例http://clojure.org/special_forms#quote,并深入了解读者和语法引用:http://clojure.org/reader