`def` is a special form and it expects exactly a symbol as a first argument (https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L541). That means that you can't do: (def (symbol "a") 1).
To generate `defs` from macro you can do the following: (defmacro def-stuff [names] `(do ~@(for [n names] `(def ~(symbol n) ~(clojure.string/upper-case n))))) (def-stuff ["foo" "bar" "baz"]) foo ;; => "FOO" (macroexpand '(def-stuff ["foo" "bar" "baz"])) ;; => (do (def foo "FOO") (def bar "BAR") (def baz "BAZ")) piątek, 2 października 2020 o 21:38:50 UTC+2 Bost napisał(a): > 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/d9d67f9a-0578-4d69-a107-07e2557fbbd5n%40googlegroups.com.