On Thu, Aug 6, 2015 at 2:35 PM, Mark Engelberg <mark.engelb...@gmail.com> wrote:
> Right, so if you use protocols, you'd just have one name: > add, sub, norm, len, neg > and use for both vectors and quadrays, rather than a v-add / q-add, etc. > > I have done this vis-a-vis Quadrays and XYZrays as both are types of vector with essentially the same API. (defprotocol VectorOps (add [this other]) (sub [this other]) (len [this]) (neg [this]) (norm [this])) https://github.com/4dsolutions/synmods/blob/master/qrays.clj > If there are things that apply only to vectors and not quadrays, you could > make those their own protocol (or individual functions). > > However I didn't take norm out of the interface though, even though it really only applies to one of the types. I had XYZray just return "this". Bad idea? (defrecord XYZray [OX OY OZ] VectorOps (norm [this] (this)) (neg [this](XYZray. (- OX) (- OY) (- OZ))) (len [this](Math/sqrt (+ (* OX OX)(* OY OY)(* OZ OZ)))) (add [this other] (XYZray. (+ OX (:OX other)) (+ OY (:OY other)) (+ OZ (:OZ other)))) (sub [this other](add this (neg other)))) > And of course, multimethods are yet another way to achieve polymorphism in > Clojure. Multimethods would really shine if you want to get into > complicated mixtures of adding vectors and quadrays, etc., or dispatch on > something other than the type (e.g., maybe pre-normalized quadrays dispatch > to something more efficient). Protocols (like traditional OO) can only > dispatch on the type of the first input. > That may be next for me. If I initialize some plain vanilla Vector with 3 coordinates, it could recognize that as XYZ and output a vector of that type, or of either type given they're inter-convertible. > > One other code simplification tip: you can destructure in the parameter, > e.g., if you were to rewrite q-neg to be a plain function as opposed to a > protocol, you could still get convenient access to the member variables by > writing it like this: > (defn q-neg [{:keys [OA OB OC OD]}] (->Quadray (- OA)(- OB)(- OC) (- OD))) > > http://www.john2x.com/blog/clojure-destructuring/ > > Before: (defn qray-to-xyzray [qray] (let [[a] [(:OA qray)] [b] [(:OB qray)] [c] [(:OC qray)] [d] [(:OD qray)] [x] [(* (/ 1 (Math/sqrt 2))(+ (- (- a b) c) d))] [y] [(* (/ 1 (Math/sqrt 2))(- (+ (- a b) c) d))] [z] [(* (/ 1 (Math/sqrt 2))(- (- (+ a b) c) d))]] (XYZray. x y z))) After: (I bet I could use destructuring to shorten the above quite a bit) > > > On Thu, Aug 6, 2015 at 1:52 PM, kirby urner <kirby.ur...@gmail.com> wrote: > >> >>> Also, don't forget to explore the test framework versus global defs and >>> print statements. >>> >>> -- >>> >> >> Right, still in my queue to get to that. Very helpful. Kirby -- 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.