Welcome! Please see the About page for a little more info on how this works.

0 votes
in ClojureScript by

Bug report:

(defn f [] 1)
=> #'cljs.user/f
(= f (with-meta f {:a 1}))
=> false ;; should be true

Per: https://clojure.org/reference/metadata
"metadata does not impact equality"

2 Answers

+1 vote
selected by
Best answer

The page also says "Two objects that differ only in metadata are equal" and "an object with different metadata is a different object."

Thus, equality is "impacted" where it relies on object identity. As is the case for compiled functions: (not= (fn []) (fn [])) regardless of metadata.

A clarification might be in order.

Are folks asking about this looking for some kind of qualification like "metadata does not impact equality (except in some cases where equality is object identity, e.g. comparing Clojure functions)" ?
Indeed perhaps that is the only built-into-Clojure example of a class that carries metadata and compares by identity.  I cruised around the Github repo (it's really nifty how you can click to see references!) and did not find another.  Of course, the sky is the limit when you consider classes not built into Clojure.  

The key thing to clarify is that the rule "metadata does not affect equality" is trumped by another rule, "changing metadata produces a new object", when those objects compare by identity, such as functions.
There are not that many kinds of things that can have metadata, neither in Clojure, and about the only that I know of that have been added outside of Clojure are additional implementations of persistent collections, and most or all of them compare equality via values, not identity.  I agree the sky is the limit in what is possible in third party libraries, but I doubt there are many examples you could find that fall into this exception.
+1 vote

I don't think this is a bug. It behaves the same as JVM Clojure.

Functions do not have value semantics so their = implementation falls back on object reference comparison.

When you add metadata to a function, it becomes a different function object, hence = returns false.