Fork me on GitHub
#clojure-dev
<
2018-05-27
>
dominicm11:05:14

(defn get-fn-reference
  [kw]
  (let [kns (namespace kw)
        snm (symbol (name kw))]
    (some-> kns
            symbol
            find-ns
            (ns-resolve snm)
            deref)))

(defmacro x
  [body]
  `~(get-fn-reference body))

(= (x clojure.core/not=)
   (get-fn-reference 'clojure.core/not=))
Repeating from #clojure. I'm confused as to why x returns a new instance of the not= function class each time.

tbaldridge14:05:24

@dominicm that's really strange, and appears to me to be some sort of equality problem

tbaldridge14:05:45

check this out

tbaldridge14:05:13

user=> (x clojure.core/not=) #object[clojure.core$not_EQ_ 0x158a3b2e "clojure.core$not_EQ_@158a3b2e"] user=> (get-fn-reference 'clojure.core/not=) #object[clojure.core$not_EQ_ 0x158a3b2e "clojure.core$not_EQ_@158a3b2e"]

tbaldridge14:05:32

stupid formatting, but they appear to be the same object, with the same pointer.

dominicm14:05:10

This is my fault for only doing the equality test after minimising my repro:

(defmacro x
  [body]
  (let [a# (get-fn-reference body)]
    `(quote ~a#)))
Does have a different pointer @tbaldridge. This was my original example.

bronsa15:05:50

evaluating the two forms separately at the repl is what makes it confusing

bronsa15:05:59

try ((fn [] (x clojure.core/not=)))

bronsa15:05:31

what is happenig is that the macro is causing a literal function value to be evaluated

bronsa15:05:59

when you do it as a single form at the repl, it runs in interpreter mode and the interpreter evaluation of a function object is the object itself

bronsa15:05:18

in a more complex form, like (= .. .. ) it gets JIT compiled

bronsa15:05:33

and the compilation of a function object is the instantiation of a new instance of its class

bronsa15:05:32

user=> (= (doto (x clojure.core/not=) println) (doto (get-fn-reference 'clojure.core/not=) println))
#object[clojure.core$not_EQ_ 0x7096b474 clojure.core$not_EQ_@7096b474]
#object[clojure.core$not_EQ_ 0x6e6d5d29 clojure.core$not_EQ_@6e6d5d29]
false

bronsa15:05:14

try using x on a function with closed overs

bronsa15:05:16

it won't work