(def message "Good job!")
(defmacro without-mischief
[& stuff-to-do]
(let [macro-message (gensym 'message)]
`(let [~macro-message "Oh, big deal!"]
~@stuff-to-do
(println "I still need to say: " ~macro-message))))
(without-mischief
(println "Here's how I feel about that thing you did: " message))
Result:
Here's how I feel about that thing you did: Good job! I still need to say: Oh, big deal!
One important thing to note is, that the symbol in the macro ('macro-message') in fact does not have to be named differently than the global symbol. It works also with the same name:
(def message "Good job!")
(defmacro without-mischief
[& stuff-to-do]
(let [message (gensym 'message)]
`(let [~message "Oh, big deal!"]
~@stuff-to-do
(println "I still need to say: " ~message))))
(without-mischief
(println "Here's how I feel about that thing you did: " message))
Result:
Here's how I feel about that thing you did: Good job! I still need to say: Oh, big deal!
On the other hand, just giving a different name to the symbol within the macro won't work:
(def message "Good job!")
(defmacro with-mischief
[& stuff-to-do]
`(let [macro-message "Oh, big deal!"]
~@stuff-to-do))
(with-mischief
(println "Here's how I feel about that thing you did: " message))
Result:
CompilerException java.lang.RuntimeException: Can't let qualified name: user/macro-message, compiling:(NO_SOURCE_PATH:1:1)
Finally, in case the symbol is a parameter of the macro, then it is possible to bind it, without gensym:
defmacro echoit
[message]
(let [message (str "echo: " message)] message))
(echoit "hello")
Result:
"echo: hello"
No comments:
Post a Comment