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.

Reply via email to