# Why this Clojure "var" error?

**URL:** https://clojureverse.org/t/why-this-clojure-var-error/6425
**Category:** Troubleshooting
**Tags:** clojure
**Created:** [August 21, 2020, 8:21pm UTC](https://clojureverse.org/t/why-this-clojure-var-error/6425 "2020-08-21T20:21:37Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Webdev\_Tory](https://clojureverse.org/user_avatar/clojureverse.org/webdev_tory/32/3781_2.png) [@Webdev\_Tory](https://clojureverse.org/u/Webdev_Tory)
#### Post date: [August 21, 2020, 8:21pm UTC](https://clojureverse.org/t/why-this-clojure-var-error/6425/1 "2020-08-21T20:21:37Z")

</div>

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](https://stackoverflow.com/questions/22116257/how-to-get-functions-name-as-string-in-clojure), 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?

```clojure
(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 ...

```

---

<div class="post-metadata">

### Author: ![seancorfield](https://clojureverse.org/user_avatar/clojureverse.org/seancorfield/32/195_2.png) [@seancorfield](https://clojureverse.org/u/seancorfield)
#### Post date: [August 21, 2020, 8:47pm UTC](https://clojureverse.org/t/why-this-clojure-var-error/6425/2 "2020-08-21T20:47:32Z")

</div>

Local symbols in macros must be gensym’d, i.e., `m#`, `fname#`, `fns#`.

---

<div class="post-metadata">

### Author: ![joinr](https://clojureverse.org/user_avatar/clojureverse.org/joinr/32/1861_2.png) [@joinr](https://clojureverse.org/u/joinr)
#### Post date: [August 21, 2020, 9:30pm UTC](https://clojureverse.org/t/why-this-clojure-var-error/6425/3 "2020-08-21T21:30:45Z")

</div>

Per sean’s response:

```
user>(pprint (macroexpand-1 '(parse-fn->string_fails foo)))

(clojure.core/let
 [user/m
  (clojure.core/-> foo var clojure.core/meta)
  user/fname
  (:name user/m)
  user/fns
  (:ns user/m)]
 (clojure.core/str userfns "/" user/fname))

(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#)))

```

now yields:

```
(clojure.core/let
    [m __16497__ auto__
     (clojure.core/-> foo var clojure.core/meta)
     fname __16498__ auto__
     (:name m __16497__ auto__)
     fns __16499__ auto__
     (:ns m __16497__ auto__)]
  (clojure.core/str fns __16499__ auto __"/" fname__ 16498 __auto__ ))

```

Which works. In the `fn-name` macro, you didn’t have this problem since you didn’t have a let binding with symbols. In the new macro, without gensyms, the unquoted symbols in the let were expanded into ns-qualified symbols, which were unable to resolve and triggered errors during evaluation of the `let` form. With the gensyms generating valid unqualified symbols for `let`, you now have valid bindings and the macro works.

---

<div class="post-metadata">

### Author: ![Webdev\_Tory](https://clojureverse.org/user_avatar/clojureverse.org/webdev_tory/32/3781_2.png) [@Webdev\_Tory](https://clojureverse.org/u/Webdev_Tory)
#### Post date: [August 21, 2020, 9:55pm UTC](https://clojureverse.org/t/why-this-clojure-var-error/6425/4 "2020-08-21T21:55:23Z")

</div>

Ah! That makes perfect sense! Thank you!

---

<div class="post-metadata">

### Author: ![system](https://clojureverse.org/uploads/default/original/2X/5/51079bf9e4b7d9466242c06cf1e43b9f8bd6da14.png) [@system](https://clojureverse.org/u/system)
#### Post date: [February 20, 2021, 9:55am UTC](https://clojureverse.org/t/why-this-clojure-var-error/6425/5 "2021-02-20T09:55:23Z")

</div>

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.
