`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.

Reply via email to