Thanks, Kovas! I looked at it a few months ago (and now just forked it), but Zach also seems to have created a separate deftype just to support this conj-ing business (and that alone is 180 LOC...) That all seems to be a huge effort though and am wondering about simpler alternatives and/or some better detailed documentation about these matters and inter-relationships. IMHO this part of Clojure seems to be very cryptic to me... Just would like to know if this particular combination of vector-style conj behavior & being self-seqable is fundamentally incompatible or if I'm missing something here? Of course, an easy solution would be to just do this:
(deftype Foo [a b] (cons [this c] (seq [a b c]))) ..but that would mean any further conj-ing will happen at the head. cons as defined in IPersistentCollection has IPersistentCollection as return type (and hence would be satisfied by PersistentVector), but it's being overridden in ISeq and so wins... Makes me wonder why conj has not been kept internally separate from cons. Wouldn't this have avoided this potential for such a conflict? On 3 September 2014 18:33, kovas boguta <kovas.bog...@gmail.com> wrote: > Not a direct answer but you might want to look at > > https://github.com/ztellman/clj-tuple/blob/master/src/clj_tuple.clj > > > > On Wed, Sep 3, 2014 at 1:13 PM, Karsten Schmidt <i...@toxi.co.uk> wrote: >> Hi all, >> >> I've defined a custom vector type and implemented various clj/cljs >> protocols, but now ended up hitting my head against some weird behaviour >> with conj (or rather cons, internally). The type >> defines a 2-element vector-like construct and my cons >> implementation would simply return a standard >> clojure.lang.PersistentVector with the given arg added like this: >> >> (deftype Foo [a b] >> clojure.lang.IPersistentCollection >> clojure.lang.Indexed >> clojure.lang.Sequential >> clojure.lang.ISeq >> clojure.lang.Seqable >> clojure.lang.Reversible >> ;; ... elided seq fn impls... >> (cons [_ c] [a b c])) >> >> However, attempting a conj results in an exception I don't understand: >> >> (conj (Foo. 1 2) 3) >> java.lang.ClassCastException: clojure.lang.PersistentVector cannot be >> cast to clojure.lang.ISeq >> at user.Foo.cons (foo.clj:13) >> user.Foo.cons (foo.clj:-1) >> clojure.lang.RT.conj (RT.java:562) >> clojure.core$conj.invoke (core.clj:83) >> ... >> >> As far as I can tell, clojure.core/conj simply calls RT.conj(coll, x), >> which just calls >> coll.cons(x): >> >> https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L604 >> >> static public IPersistentCollection conj(IPersistentCollection coll, Object >> x){ >> if(coll == null) >> return new PersistentList(x); >> return coll.cons(x); >> } >> >> So where in that call path is there an attempt or requirement to cast >> to an ISeq? >> >> I've been comparing notes (as far as this possible) with the default >> PersistenVector implementation, but not sure where I'm going wrong >> here... >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> Note that posts from new members are moderated - please be patient with your >> first post. >> To unsubscribe from this group, send email to >> clojure+unsubscr...@googlegroups.com >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with your > first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- Karsten Schmidt http://postspectacular.com | http://toxiclibs.org | http://toxi.co.uk -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.