2014-06-20 105 views
2

我通過一些實例的Clojure從工作braveclojure:爲什麼這個clojure函數不能執行?

http://www.braveclojure.com/writing-macros/

目前我想基本上執行此

(ns turtle (:use clojure.pprint)) 

(def criticisms {:good "good code:" :bad "bad code:"}) 

(defn criticize-code 
    [[critkey code]] 
    `(println (~critkey criticisms) (quote ~code))) 

(defmacro code-critic 
    [code-evaluations] 
    `(do [email protected](map criticize-code code-evaluations))) 

(println "executed code critic") 
(code-critic {:good (+ 1 1) :bad (1 + 1)}) 
(println "code critic expansion") 
(pprint (macroexpand '(code-critic {:good (+ 1 1) :bad (1 + 1)}))) 

;why isn't this executing? 
(println "criticize code expansion") 
(criticize-code [:good '(+ 1 1)]) 

,我可以驗證批評代碼返回正確格式的代碼通過println;但我實際上無法執行它......有人可以告訴我我做錯了什麼嗎?

謝謝!

回答

3

函數criticize-code被調用。函數體中的準引號``是語法引用的讀取器宏,這意味着在通過語法引用讀取器的行程之後,以下形式的println將作爲數據結構返回而不是執行。如果你想在REPL治療所產生的數據結構代碼criticize-code功能是語義上等同於

(defn criticize-code 
    [[critkey code]] 
    (list 
    'clojure.core/println 
    (list critkey 'turtle/criticisms) 
    (list 'quote code))) 

,您可以直接eval它。

turtle=> (criticize-code [:good '(+ 1 1)]) 
(clojure.core/println (:good turtle/criticisms) (quote (+ 1 1))) 
turtle=> (eval (criticize-code [:good '(+ 1 1)])) 
good code: (+ 1 1) 
nil 

那麼,爲什麼你會想要一個這樣的功能?作爲一個宏的幫手,這裏爲code-critic。宏處理代碼作爲數據作爲代碼。因此,如果您在as-data階段使用輔助功能,則需要將其結果作爲數據返回。否則,要編譯的代碼只在「編譯」時執行,而返回值(println返回nil)會被編譯。

相關問題