Hi all,

I'd like to extend some protocol to objects of classes that were
compiled in memory, and thus I don't have the class handy as literal but
have to resolve it.

To simplify the issue, my code is basically like this:

--8<---------------cut here---------------start------------->8---
(defprotocol BlaBla
  (bla [this]))
 
(extend-protocol BlaBla
  (class 17)  (bla [this] (inc this))
  (class "s") (bla [this] (reverse this))
  (class \s)  (bla [this] "foo"))
--8<---------------cut here---------------end--------------->8---

But that extend-protocol form does not compile:

--8<---------------cut here---------------start------------->8---
nth not supported on this type: Character
  [Thrown class java.lang.UnsupportedOperationException]
Backtrace:
  0: clojure.lang.RT.nthFrom(RT.java:835)
  1: clojure.lang.RT.nth(RT.java:785)
  2: 
clojure.core$emit_hinted_impl$hint__5517$fn__5519.invoke(core_deftype.clj:710)
  3: clojure.core$map$fn__3811.invoke(core.clj:2432)
  4: clojure.lang.LazySeq.sval(LazySeq.java:42)
  5: clojure.lang.LazySeq.seq(LazySeq.java:60)
  6: clojure.lang.RT.seq(RT.java:466)
  7: clojure.lang.RT.countFrom(RT.java:519)
  8: clojure.lang.RT.count(RT.java:512)
  9: clojure.lang.Cons.count(Cons.java:49)
 10: clojure.lang.Compiler.analyze(Compiler.java:6207)
--8<---------------cut here---------------end--------------->8---

The problem might be that extend-protocol expands into a sequence of
extend-type calls, and that into an extend form.  The extend-type docs
say

    Propagates the class as a type hint on the first argument of all
    fns.

Clearly, in my case forms like (class 17) don't work as type hint.  That
said, evaling them won't work either, cause my real code is more like:

--8<---------------cut here---------------start------------->8---
(let [x (foo)]
  (extend-protocol BlaBla
    (get-class x 'Foo) (bla [this] ...)
    (get-class x 'Bar) (bla [this] ...)))
--8<---------------cut here---------------end--------------->8---

Anyway, I can simply use 3 extend to achieve the same, and that compiles
and works fine:

--8<---------------cut here---------------start------------->8---
(extend (class 17)  BlaBla {:bla (fn [this] (inc this))})
(extend (class \s)  BlaBla {:bla (fn [this] "foo")})
(extend (class "s") BlaBla {:bla (fn [this] (reverse this))})
--8<---------------cut here---------------end--------------->8---

However, it's much less convenient.  In my real code, I don't have 3 but
~20 classes that should participate in the BlaBla protocol.

So, is this a bug or is it just me trying to do unsupported things?

IMHO, if the class is not given literally, then the type hint should be
omitted (maybe with a warning)...

Bye,
Tassilo

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

Reply via email to