I can "generate" a def with a macro.
(defmacro my-def [my-name]
`(def ~my-name 42))
(my-def a)
a; => 42
If I try to do something similar with a list
(defmacro my-defs [my-names]
`(do
~@(for [name# my-names]
`(def ~name# 42))))
(my-defs (a b c))
(macroexpand '(my-defs (a b c))); => (do (def a 42) (def b 42) (def c 42))
It works as long as I use a literal list as input. But as soon as I want to pass in a var
(def my-list '(a b c))
(macroexpand '(my-defs my-list)); => Don't know how to create ISeq from: clojure.lang.Symbol
I struggle to access the value of my-names. I can't use ~my-names as it is already used in a unquote-splice (~@) and would lead to an "Attempt[...] to call unbound fn".
What am I missing?
Do I need to use (var-get (resolve my-names))?
Do macros in these cases need to "detect" if the passed argument is a literal value or a var and act accordingly in order to work for both?
Or is it idiomatic to use eval to avoid this?
Addressing @Alan Thompson's question "[...] why [do] you want to do this?": I have a specification (a deeply nested map) of "resources" and it would be rather handy to have a macro generate defs (records) for these resources in order to use them down the line. So I guess no reason out of the ordinary "It would DRY up things". :) At this time I found a way by wrapping my-names in an eval. The question that remains is: Is this idiomatic, or is there a better way?