On one of my pet projects I have a bunch of macros, and sometimes I want to be able to read metadata from macro definition. The reason being that sometimes my other macros should expand differently depending on input form. Of course, it is rather simpler to just expand and then read metadata, but I wonder if it's possible to do while macro is expanding.
Consider following macro:
(defmacro stackoverflow
{:example 23}
[& args]
(comment "This is just an example"))
It is perfectly simple to read metadata from macro in regular function.
(defn- -example?
[form-var]
(-> form-var
meta
:example
some?))
:=> (-example? #'stackoverflow)
true
It is not hard to do inside another macro as well:
(defmacro example?-macro[form]
`(-example? (var ~form)))
:=> (example?-macro stackoverflow)
true
But I couldn't find a way to get meta while macro is expanding:
(defmacro test-example? [form]
(if (example?-macro form)
(println "It is indeed an example")
(println "It is not and example!")))
> Unable to resolve var: form in this context
I want my test-example?
to do different job depending on the input form, but couldn't find a way to do it.
In short the whole question boils to: How to take var from input macro inside macro without expanding like so:
;; This is desired behaviour
(defmacro imagining-solution
[form]
(if (:example `(meta (var ~form)))
(println "It is indeed an example")
(println "It is not and example!")))
;; But one can only dream about
Immediately after posting this question ;) found a solution here: Accessing argument's metadata in Clojure macro
Just use resolve
function!