Hello Jonathan,
In my experience, an error along the lines of "class Foo cannot be cast to
Foo" is usually caused by re-evaluating class definitions, either by
reloading files or by re-evaluating definitions in your REPL or IDE.
Here is a smaller example that demonstrates the problem:
(deftype Foo [x])
(def a-foo (Foo. 1))
(defn use-foo [^Foo foo]
(prn (.x foo)))
;; Re-evaluate the definition of Foo,
;; perhaps in a REPL or editor:
(deftype Foo [x])
(type a-foo) ;;=> user.Foo
(= Foo (type a-foo)) ;;=> false
(use-foo a-foo)
;; java.lang.ClassCastException:
;; user.Foo cannot be cast to user.Foo
The object `*a-foo*` is an instance of the **first** definition of the type
Foo, which was overwritten by the **second** definition of the type Foo.
This problem is caused by a combination of Clojure's runtime generation of
Java classes and the way JVM ClassLoaders work.
-S
On Sunday, January 19, 2014 9:20:03 PM UTC-5, Jonathan Barnard wrote:
>
> For fun, I've been porting a very simple particle animation from Java to
> Clojure. It was somewhat slow so to see how fast I could make it I decided
> to try using mutation. I've defined a Particle type, and a PSlice type that
> contains an array of objects and a length (number of non-nil objects in the
> slice), but when I try to provide type hints for this slice type, I get the
> error:
>
> *ClassCastException MyProject.core.PSlice cannot be cast to *
>
> *MyProject.core.PSlice *Is this a bug, or am I doing something wrong? My
> code defining the two types is:
>
> (definterface IPt
> (^Double gx []) (^Double gy []) (^Double gz []) (^Double gvx [])
> (^Double gvy []) (^Double gvz []) (^Double gR []) (^Double glife [])
> (^Boolean gis [])
> (sx [^Double v]) (sy [^Double v]) (sz [^Double v]) (svx [^Double v])
> (svy [^Double v]) (svz [^Double v]) (sR [^Double v]) (slife [^Double v])
> (^Boolean sis [^Boolean v]))
>
> (deftype Particle [^:unsynchronized-mutable ^Double x
> ^:unsynchronized-mutable ^Double y ^:unsynchronized-mutable ^Double z
> ^:unsynchronized-mutable ^Double vx
> ^:unsynchronized-mutable ^Double vy ^:unsynchronized-mutable ^Double vz
> ^:unsynchronized-mutable ^Double R
> ^:unsynchronized-mutable ^Double life ^:unsynchronized-mutable ^Boolean is]
> IPt
> (gx [_] x) (gy [_] y) (gz [_] z) (gvx [_] vx) (gvy [_] vy) (gvz [_] vz)
> (gR [_] R) (glife [_] life) (gis [_] is)
> (sx [this v] (set! x v)) (sy [this v] (set! y v)) (sz [this v] (set! z
> v))
> (svx [this v] (set! vx v)) (svy [this v] (set! vy v)) (svz [this v]
> (set! vz v))
> (sR [this v] (set! R v)) (slife [this v] (set! life v)) (sis [this v]
> (set! is v)))
>
> (definterface ISlice
> (^Long gLen [])
> (sLen [^Long x])
> (^Particle gPt [^Long n])
> (sPt [^Long n ^Particle pt] ))
>
> (deftype PSlice [^"[Ljava.lang.Object;" pts ^:unsynchronized-mutable ^Long
> len]
> ISlice
> (gLen [_] len)
> (sLen [this new-len] (set! len new-len))
> (gPt [this n] (aget pts n))
> (sPt [this n pt] (aset pts n pt)))
>
>
> Then the error occurs if I define a PSlice, such as by:
>
> (def tslice (PSlice. (make-array Object 100) 0))
>
> and a function:
>
> (defn test-fn [^PSlice slice]
> (print (.gLen slice))
> )
>
> Then call (test-fn tslice).
>
> Note that the function will work as intended if no type hints are
> provided, but will run quite slowly due to reflection, defeating the point
> of using mutation.
>
--
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/groups/opt_out.