I’m in the process of learning Clojure macros, and I’m getting a NullPointerException when trying to use macroexpand-1 on this macro:
(def config {:ns 'bulbs.neo4jserver.client,
:root-uri "http://localhost:7474/db/data/"})
(def data {:name "James"})
(defmacro create
[config data]
`(~(ns-resolve (:ns config) 'create-vertex) config data))
(macroexpand-1 '(create config data))
Trying to compile this returns:
Unknown location:
error: java.lang.NullPointerException
Compilation failed.
But evaluating the macro’s body…
`(~(ns-resolve (:ns config) 'create-vertex) config data)
…returns this…
(#'bulbs.neo4jserver.client/create-vertex bulbs.vertices/config bulbs.vertices/data)
…which is what I think I want.
UPDATE: If I manually replace (:ns config) with 'bulbs.neo4jserver.client then the error goes away — how do you make (:ns config) play nice?
You’re trying to mix macroexpand-time and runtime information. The local “config” does not contain the contents of the #’config var, but instead is the symbol ‘config.
If you look at the full stack trace, not just the error message, you’ll see that ns-resolve is being passed a nil:
Once you understand the following you will understand your original problem: