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

Alo*_*orz 10 clojure apostrophe

来自"Clojure的喜悦"一书:

第一个例子:

(def fifth (comp first rest rest rest rest))
(fifth [1 2 3 4 5])
;=> e
Run Code Online (Sandbox Code Playgroud)

第二个例子:

(defn fnth [n]
  (apply comp
    (cons first
      (take (dec n) (repeat rest)))))
((fnth 5) '[a b c d e])
;=> e
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*ark 9

在第二个示例中,您必须使用撇号,因为您希望阻止对向量元素的求值.如果您删除撇号,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]
Run Code Online (Sandbox Code Playgroud)

请注意,您不必使用带有数字的aphostrophe,因为他们自己评估:

user> 1
;; => 1
user> 2
;; => 2
user> [1 2 3]
;; => [1 2 3]
Run Code Online (Sandbox Code Playgroud)

虽然符号没有,但Clojure将搜索给定符号绑定的值:

user> x
CompilerException java.lang.RuntimeException: Unable to resolve symbol: x
Run Code Online (Sandbox Code Playgroud)

因此,在进入函数之前,了解此信息以及函数的参数被评估的事实,应该清楚为什么以及何时在向量之前使用撇号.