2

Why does this:

`(def ^:private name 1 )

evaluate to:

(def namespace/name 1) 

and not to this:

(def ^:private namespace/name 1) 

i'm just trying to write a little macro:

(defmacro def- [name val] `(def ^:private ~name ~val))

but it expands to:

(macroexpand-1 `(def- foo 12))
=> (def namespace/foo 12)
szymanowski
  • 1,359
  • 1
  • 14
  • 25
  • Do you know how metadata works? – Chiron Jan 03 '14 at 13:40
  • no sorry, maybe i should dig this way, thank you – szymanowski Jan 03 '14 at 13:41
  • I maybe wrong but I think you need `with-meta` here. http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/with-meta – edbond Jan 03 '14 at 14:13
  • 1
    You should use the regular quote with `macroexpand-1`; with it your call becomes `(macroexpand-1 '(def- foo 12))`, which returns the actual expansion of `(def foo 12)`. With the backtick, the form that gets macroexpanded is `(namespace/def- namespace/foo 12)`; it is this form that expands to `(def namespace/foo 12)`, which is an error (the "name" symbol passed to `def` may not be namespace-qualified). The metadata issue is as described in kotarak's answer to [the question linked to be Guillermo](http://stackoverflow.com/questions/7754429/clojure-defmacro-loses-metadata). – Michał Marczyk Jan 03 '14 at 16:49

1 Answers1

2

Because clojure defmacro loses metadata, since ^ is a reader macro.

And :private is symbol metadata, so it's lost.

Look at the answer to the question on the first link for a solution.

Community
  • 1
  • 1
guilespi
  • 4,672
  • 1
  • 15
  • 24
  • If this is a duplicate, please don't write an answer, but leave a comment or flag the question. At 3000 rep, you'll be able to cast close votes for this. – sloth Jan 03 '14 at 15:35
  • Ack'ed, question is posed different so not exactly a duplicate, improved the answer to close the gap between the question asked here and the solution provided in the original link. – guilespi Jan 03 '14 at 16:06
  • 2
    This is true but not relevant to the problem he's actually seeing - misusing metadata in this way does cause his `:private` to be lost, but as Michal says in his comment, the main issue is that he's using `\`` in his call to `macroexpand`, instead of `'`, so the extra `namespace/` qualifier is added in before his macro even sees the name. – amalloy Jan 03 '14 at 21:44