We were attempting to write functions could round-trip function references to strings and, though we eventually figured this out in a different way, our first attempts brought a very confusing error. It seems to have something to do with how var works, and some underlying characteristic of Clojure that I would love to understand.
We were adapting this macro, which worked in the REPL: (defmacro fn-name [f] `(-> ~f var meta :name str)) . But it failed when written as a larger fn, below, and even with macro-expand1 it wasn’t clear what was going wrong, although trial and error indicated that it has something do with with how var works. Can anyone shed some light on the nature of the problem?
(defn foo [] nil)
(defmacro parse-fn->string_fails
"Should parse a function, like `clojure.core/str`, to a string \"clojure.core/str\" "
[f]
`(let [m (-> ~f var meta)
fname (:name m)
fns (:ns m)]
(str fns "/" fname)))
(parse-fn->string_fails foo)
;; =>
;; Call to clojure.core/let did not conform to spec.
;; #:clojure.spec.alpha{:problems ({:path [:bindings :form :local-symbol], :pred clojure.core/simple-symbol?, :val logging.core/m, :via [:clojure.core.specs.alpha/bindings :clojure.core.specs.alpha/bindings ...