2014-01-13 37 views
2

我在clojure中使用宏時遇到問題。這是我想要做的。Clojure:宏中的錯誤。 「沒有這樣的變種」

(defmacro working-example [] 
    '(+ foo 1)) 

(defn working-function [foo] 
    (working-example)) 

(working-function 2) ; => 3 

(defmacro broken-example [bar] 
    `(+ foo ~bar)) 

(defn broken-function [foo] 
    (broken-example 1)) ; => I get error here. 

(broken-function 2) ; Should be 3. 

我想破,例如宏僅替換文本一樣工作,例如做。爲什麼它不起作用,我應該怎樣才能使它起作用?

回答

5

我對Clojure相當陌生,但我會盡力向您解釋發生了什麼。引用和反引用在他們如何對待符號方面有所不同。例如,您可以編寫導致的細微差別類似的代碼:

user=> '(+ foo 2) 
(+ foo 2) 
user=> `(+ foo 2) 
(clojure.core/+ user/foo 2) 

注意只使用反引號如何「結合」的符號對應的命名空間(clojure.core+userfoo)。相反,引用只是將符號當作對待。如果你想正確撰寫你的斷功能,您可以使用list語法:

(defmacro broken-example [bar] 
    (list '+ 'foo bar)) 

(defn broken-function [foo] 
    (broken-example 1)) 

(broken-function 2) 

現在broken-function輸出預期的結果。

編輯

現在由於A.下面韋伯評論,你也可避免命名空間中通過使用此語法結合:

(defmacro broken-example [bar] 
    `(+ ~'foo ~bar)) 
+1

「我知道有防止反引號來的一種方式在命名空間中查找符號「 - '\'(+〜'foo 2)' –

+0

哦,謝謝A. Webb。我會更新該文章的完整性。 –