Clojure何时是向量之前需要的撇号

时间:2014-10-11 08:46:32

标签: clojure apostrophe

来自" Clojure的喜悦"书:

第一个例子:

(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

为什么在第二个例子中(但不是在第一个例子中)我需要一个撇号?没有第二个例子会引发错误。

2 个答案:

答案 0 :(得分:8)

在第二个例子中,你必须使用撇号,因为你想要阻止评估向量的元素。如果删除撇号,Clojure将尝试解析符号ab等,就像它们绑定某些值一样。

示例:

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