Reputation: 47
I'm working through some clojure examples from braveclojure:
http://www.braveclojure.com/writing-macros/
Currently I am trying to execute this
(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 ~@(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)])
Basically, I can verify that criticize-code returns properly formatted code through println
; but I cannot actually execute it...can someone please tell me what I'm doing wrong?
Thank you!
Upvotes: 2
Views: 100
Reputation: 26446
The function criticize-code
is being invoked. The quasi-quote, `, in the body of the function is a reader macro for syntax-quote, which means the following println
form, after its trip through the syntax-quote reader, will be returned as data structure rather than executed. The criticize-code
function is semantically equivalent to
(defn criticize-code
[[critkey code]]
(list
'clojure.core/println
(list critkey 'turtle/criticisms)
(list 'quote code)))
If you want to treat the resulting data structure as code at the REPL, you can eval
it directly.
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
So why would you want a function that works like this? As a helper to a macro, as here for code-critic
. Macros deal with code-as-data-as-code. Therefore, if you stick in a helper function at the as-data
stage, it will need to return its result as data. Otherwise, the code you want to be compiled is just executed at "compile" time with its return value (println
returns nil
) compiled instead.
Upvotes: 3