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

0 votes
in Clojure by

{{print-dup}} for sorted sets and maps presume a nonexistent static {{create}} method that takes an {{IPersistentCollection}}


user=> (print-dup (sorted-set 1) out)

=(clojure.lang.PersistentTreeSet/create [1])


Can't read back

(read-string "#=(clojure.lang.PersistentTreeSet/create [1])") ClassCastException Cannot cast clojure.lang.PersistentVector to clojure.lang.ISeq java.lang.Class.cast (Class.java:3356)

Possible Fixes
add {{create}} methods taking {{IPersistentVector}} to collections
emit something different from {{print-dup}}

4 Answers

0 votes

Comment made by: alexmiller

It's trying to invoke PersistentTreeSet.create(ISeq) with (link: "123"). It's not clear to me where the vector comes from?

0 votes
_Comment made by: tonsky_

It’s a particular case of CLJ-1461. Vector comes from reading output of print-dup:

(defrecord Rec [f])

(binding [*print-dup* true]
  (prn (Rec. (sorted-set 1))))
;; => #tonsky.Rec[#=(clojure.lang.PersistentTreeSet/create [1])]

I already have a patch for PersistentTreeSet (attached here). Can look into CLJ-1461 later.
0 votes

Comment made by: mikerod

This won't work for sorted sets (or maps) that are defined with a custom Comparator though via fn's like sorted-set-by etc. I think the round-trip print to read result would then be confusing and incorrect right?

Even more troublesome to me here is that I see no clear way to make print-dup capable of handling the case of a custom Comparator correctly. Arbitrary functions are black boxes and we have no generally, effective way to print-dup them (based on my research I assume this to be correct). We can always make special wrapped fn's for that, but again, not general.

0 votes
Reference: https://clojure.atlassian.net/browse/CLJ-1733 (reported by tonsky)