Re: symbol is not a symbol in (def (symbol "x") ...) ???

2020-10-03 Thread tome...@gmail.com
`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  ...)` 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.


Re: symbol is not a symbol in (def (symbol "x") ...) ???

2020-10-05 Thread tome...@gmail.com
Yes, that's almost good solution and works on runtime.
Almost because I would use `doseq` instead of `for`. `for` generates lazy 
seq.

poniedziałek, 5 października 2020 o 11:41:53 UTC+2 peter...@gmail.com 
napisał(a):

> On Friday, 2 October 2020 at 20:38:50 UTC+1 Bost wrote:
>
>> I have a problem with `def` in macros. I'd like to create a bunch of 
>> following definitions:
>>
>> Also possible to do without macros:
> (defn def-stuff [xs] (for [x xs] (intern *ns* (symbol x) (upper-case x
> This seems to work for me, if anyone knows why it's not right, I'd love to 
> hear.
>
>

-- 
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/9825f948-efeb-426b-97fd-189f820b3e22n%40googlegroups.com.


Re: symbol is not a symbol in (def (symbol "x") ...) ???

2020-10-05 Thread tome...@gmail.com
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  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  
>> 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  ...)` 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
>>>  
>>> 
>>> .
>>>
>> -- 
>> 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
>>  
>>