On 7/21/12 7:33 AM, ChrisR wrote:
I am wondering if there is a simpler idiom to deal with functions on primitives that only differ by type hints (see example), this is the current idiom I am using which is starting to appear in my codebase, however I feel like whenever this much replication occurs I am missing a key point somewhere in my learning of Clojure. Any advice appreciated.

(:import (cern.colt.matrix.tfloat.impl DenseFloatMatrix2D SelectedDenseFloatMatrix2D))

(defmulti aggregate-rows class)

(defmethod aggregate-rows DenseFloatMatrix2D [matrix]
  (let [n-rows (.rows ^DenseFloatMatrix2D matrix)
        n-columns (.columns ^DenseFloatMatrix2D matrix)
        aggregate (float-array n-rows 0)]
    (dotimes [i n-rows]
      (dotimes [j n-columns]
        (aset aggregate i
              (unchecked-add (aget aggregate i)
                 (.getQuick ^DenseFloatMatrix2D matrix i j)))))
    aggregate))

(defmethod aggregate-rows SelectedDenseFloatMatrix2D [matrix]
  (let [n-rows (.rows ^SelectedDenseFloatMatrix2D matrix)
        n-columns (.columns ^SelectedDenseFloatMatrix2D matrix)
        aggregate (float-array n-rows 0)]
    (dotimes [i n-rows]
      (dotimes [j n-columns]
        (aset aggregate i
              (unchecked-add (aget aggregate i)
                 (.getQuick ^SelectedDenseFloatMatrix2D matrix i j)))))
    aggregate))

I've noticed that when wrapping java libs like this you sometimes have to live with a certain amount of duplication if you want/need type hints. However, if the java lib is designed well with interfaces you can get away with type hinting with the shared interface (or superclass as Dennis already mentioned).

Kinda off topic, but I have some colt wrappers on github if you want to take a look at the approach I took:
https://github.com/bmabey/claw/blob/master/src/claw/core.clj

You'll notice that I had to have some duplication as well for type hinting in my protocols. Once I wrapped each matrix type in the main protocols all my main API functions can call them uniformly without having to worry about type hints.

BTW, the best place to see how to use the wrappers are the tests (midje facts), which includes an example on how I would my #'reduce-rows function to do what your #'aggregate-rows is doing:

https://github.com/bmabey/claw/blob/master/test/claw/test/core.clj#L110

-Ben

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