Do you know about macroexpand? user=> (defmacro m1 [v] `(def (symbol ~v))) #'user/m1 First argument to def must be a Symbol user=> (macroexpand '(m1 "foo")) (def (clojure.core/symbol "foo")) user=> (defmacro m2 [v] `(def ~(symbol v))) #'user/m2 user=> (macroexpand '(m2 "foo")) (def foo)
The trick here is that you need to convert v into a symbol when the macro is expanded, not at runtime. On Oct 2, 2020 at 3:37:52 PM, Rostislav Svoboda <rostislav.svob...@gmail.com> wrote: > I have a problem with `def` in macros. I'd like to create a bunch of > following definitions: > > (def foo "FOO") > (def bar "BAR") > (def baz "BAZ") > > So I wrote a macro: > > user=> (defmacro def-stuff [v] `(def (symbol ~v) > (clojure.string/upper-case ~v))) > #'user/def-stuff > > And I'd like to do map this macro over a vector of strings: > > user=> (map (fn [n] (def-stuff n)) ["foo" "bar" "baz"]) > Syntax error compiling def at (REPL:1:14). > First argument to def must be a Symbol > > A little check indicates that everything should be fine: > user=> (symbol? (symbol "foo")) > true > > but it is not: > user=> (def (symbol "foo") "FOO") > Syntax error compiling def at (REPL:1:1). > First argument to def must be a Symbol > > ??? > Interestingly enough: > > user=> (defmacro def-stuff [v] `(def v (clojure.string/upper-case ~v))) > #'user/def-stuff > user=> (map (fn [n] (def-stuff n)) ["foo" "bar" "baz"]) > (#'user/v #'user/v #'user/v) > > Strangely enough a `v` gets (re)defined. > > To me it looks like the lexical-binding of macro-parameters is ignored if > there's a `(def <macro-param> ...)` inside this macro. > > Can anybody explain what's going on here please? Thanks. > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/clojure/CAEtmmex6Kn%3DQ8AZ-AyYoZLpYVu7%2BWnX3u7vQBgydiA%2B1jUt9Rw%40mail.gmail.com > <https://groups.google.com/d/msgid/clojure/CAEtmmex6Kn%3DQ8AZ-AyYoZLpYVu7%2BWnX3u7vQBgydiA%2B1jUt9Rw%40mail.gmail.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/clojure/CAKL9L2kXoG-9psgnbNKtdRBsAW3si_bRCDFpwB50thmM610MKg%40mail.gmail.com.