Hmm... since ISeq extends IPersistentCollection and overrides the
latter's return type, cons must return an ISeq. So do I understand it
correctly, that one *can't* have a deftype which returns itself as
Seqable *and* has vector-style conj behavior (i.e. append at tail
position)?

K.

On 3 September 2014 18:13, 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...



-- 
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.

Reply via email to