Fork me on GitHub
#clojurescript
<
2023-05-24
>
Lidor Cohen09:05:44

Hello everyone 🙂 Is there a way to implement IWithMeta & IMeta for primitives (#object[Number], #object[Boolean], #object[Function], etc...)?

p-himik09:05:56

Yes - it's mentioned in the docstring of extend-type.

p-himik09:05:01

ClojureScript 1.11.60
cljs.user=> (meta 1)
nil
cljs.user=> (extend-type number IMeta (-meta [n] (println 'meta n)))
#object[Function]
cljs.user=> (meta 1)
meta 1
nil

thheller09:05:27

for intents and purposes there is not no

thheller09:05:49

you can fake it but it won't behave properly, since primitives don't have "instances".

thheller09:05:12

ie. every 1 will have the same meta

thheller09:05:42

function has meta fn already, so that yes but not numbers, booleans, strings

p-himik09:05:02

Ah yeah, in my answer I focused only on the "implement a protocol for primitives" side of it.

thheller09:05:43

yeah, shouldn't do that for the meta protocols 😛

Lidor Cohen14:05:48

another small question: can someone explain the following?:

(satisfies? IWithMeta +) ;; => false
(with-meta + {:hello "world"}) ;; works
How does + support with-meta yet fail satisfies?, is there a more reliable way to test for support of with-meta (except try & catch)?

p-himik14:05:10

I think the source is pretty much self-describing:

ClojureScript 1.11.60
cljs.user=> (source with-meta)
(defn with-meta
  "Returns an object of the same type and value as obj, with
  map m as its metadata."
  [o meta]
  (if (js-fn? o)
    (MetaFn. o meta)
    (when-not (nil? o)
      (-with-meta o meta))))

🙏 2