One quick hint, since `intern` is a function with side effects (mutates ns 
state) I would use `run!` instead of `map` (which is lazy).

Cheers!

poniedziałek, 5 października 2020 o 14:02:22 UTC+2 Bost napisał(a):

> This is pure gold - your answers! Thanks a lot. So the take outs and key 
> ideas for me are:
>
> - The syntax quote '`', unquote '~' and I expect also the unquote splicing 
> '~@' can be nested.
> - A global var doesn't need to be created by the `def` (in macro). Use the 
> `intern` function directly (and be aware of possible lazy evaluation).
> - There's more to `macroexpand` than just the debugging. Think out of the 
> box!*
>
> At the first glance I like the "use `intern`" idea at most and I'll give 
> it a try it the following form:
>     (defn def-stuff [x] (intern *ns* (symbol x) x))
>     (map def-stuff [...])
> This way, I naively hope, I can reason about it the functional-programming 
> way:
>     Just create a function and map it over something. No code generation 
> or expansion trickery involved.
>
> Again, thank you very much, I consider adding your examples to 
> https://clojuredocs.org/clojure.core/def
>
> Bost
>
> *as always :)
>
>
> Le lun. 5 oct. 2020 à 13:02, Jeremy Heiler <jeremy...@gmail.com> a écrit :
>
>> 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 <rostisla...@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 clo...@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+u...@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+u...@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 clo...@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+u...@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+u...@googlegroups.com.
>>
> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/clojure/CAKL9L2kXoG-9psgnbNKtdRBsAW3si_bRCDFpwB50thmM610MKg%40mail.gmail.com
>>  
>> <https://groups.google.com/d/msgid/clojure/CAKL9L2kXoG-9psgnbNKtdRBsAW3si_bRCDFpwB50thmM610MKg%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/c5afc190-1bbd-40e6-a452-24012f0b807en%40googlegroups.com.

Reply via email to