There is no convenient way to inherit functionality. But there are a couple other routes, perhaps one of these will appeal to you -
* Just use your rich Java library from Clojure, perhaps providing a high performance integration the same way that Clojure does via RT.java and inlining * Use macros - see gvec.clj or defrecord.clj * Write the shared code as helper functions that can deal with types via a common access protocol It's admittedly a real challenge taking a inheritance-centric design and making it work in Clojure. But I consider it a fun and eye-opening one. David On Wed, Sep 28, 2011 at 6:40 AM, toxi <toxmeis...@gmail.com> wrote: > Dear Clojurians, > > I picked up Clojure a few months ago and find it hugely fascinating. > I've been working mainly with Java for the past few years and now > trying to overcome the un-learning curve in regards to polymorphism > and solving it with records & protocols instead. > > My aim is to port my library collection (http://toxiclibs.org) to > Clojure. The core libs contain several type hierarchies of geometric > entities (vectors, particles, shapes etc.) So I'm currently trying to > find the best solution to the following (but would just like to get my > head around this kind of problem in general): > > In Java I've got a Vec2D class which has a large amount of methods > (80+) for vector algebra. I've also got a VerletParticle2D which > subclasses Vec2D, and adds a bunch of new properties (and methods). In > Java I only needed to implement the generic vector behaviours (adding, > normalizing, scaling etc.) once in the Vec2D class and they become > automatically available in VerletParticle2D. In Clojure I've tried to > achieve this with protocols, but I can't see a way how to provide the > same thing without having to re-implement the entire IVec2D protocol > for both record types. The following works of course, but IMHO > violates the DRY principle: > > (defprotocol IVec2D > (vadd [this v] "produces 2d vector sum of given vectors")) > > (defrecord Vec2D [^double x ^double y] > IVec2D > (vadd [this v] (Vec2D. (+ x (:x v)) (+ y (:y v))))) > > (defrecord VerletParticle2D > [^double x ^double y ^double mass behaviors constraints] > IVec2D > (vadd [this v] > (VerletParticle2D. (+ x (:x v)) (+ y (:y v)) mass behaviors > constraints))) > > (def v (Vec2D. 23 42)) > (def p (VerletParticle2D. 11 22 3 [] [])) > > (vadd v p) ; => #:user.Vec2D{:x 34.0, :y 64.0} > (vadd p v) ; => #:user.VerletParticle2D{:x 34.0, :y 64.0, :mass > 3.0, :behaviors [], :constraints []} > > The other option I thought of is using assoc instead of explicitly > creating new instances and then injecting these implementations via > the extend function: > > (def IVec2D-impl { > :vadd (fn [this v] > (assoc this :x (+ (:x this) (:x v)) :y (+ (:y this) (:y v)))) > }) > > (defrecord Vec2D [^double x ^double y]) > (defrecord VerletParticle2D [^double x ^double y ^double mass > behaviors constraints]) > > (extend Vec2D IVec2D IVec2D-impl) > (extend VerletParticle2D IVec2D IVec2D-impl) > > This is more concise, but also quite a lot slower due to assoc. Are > there any other options I can try to realise this? Also, in the latter > case, why does (parents Vec2D) doesn't list IVec2D, but in the former > it does? How can I express a VerletParticle2D is a Vec2D? Using derive > doesn't work with records... > > Super grateful for any answers/pointers/solutions! > > Thanks, K. > > -- > 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 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