extending a protocol to arrays and handle nesting too

66 views
Skip to first unread message

Jim - FooBar();

unread,
Jun 19, 2013, 1:59:37 PM6/19/13
to clo...@googlegroups.com
Hi again,

quick question:


Is it at all possible to extend a protocol to a particular primitive
array type but also handle nesting of arrays? A double[] is not the same
class as double[][] which in turn is not the same Class as double[][][]
etc etc and there is no interface tying them together.... So this means
I can't do the regular trick that I can do with any other Collection type.

example:

(defprotocol Normalisable
(normalise [this transformer]))

(extend-protocol Normalisable
Number
(normalise [this transform]
(transform this))
String
(normalise [this stem]
(stem this))

java.util.List ;;if this fires, we're dealing with a Java list-like
collection - return a vector
(normalise [this transform]
(if (instance? java.util.Collection (first this)) ;;handle nesting at
the top interface and pray that an extension-point for that type exists
(mapv #(normalise % transform) this)
(let [top (delay (apply max this))
bottom (delay (apply min this))]
(mapv (fn [x] (normalise x #(transform % [top bottom]))) this))) )


and so forth for Collections... for arrays it's the same story (but with
amap) but it will only work for 1d arrays. Extending to object-arrays,
thinking that the outer array is an Object[], fails miserably. How on
earth am I supposed to handle nesting in a general way?

thanks in advance...

Jim

Cedric Greevey

unread,
Jun 19, 2013, 8:03:00 PM6/19/13
to clo...@googlegroups.com
I doubt you can extend it to "all n-dimensional arrays of foo".

What you can do, though, is (defmacro add-support-for-dimension [n] `(extend-protocol ...)) and document that users of your library should invoke this macro once for each number of dimensions that will need supporting. If that set's open-ended, they can construct and eval calls to the macro at run time, though that's a bit icky, every time a new dimension is first encountered.

If it's true that if you have a protocol extended to a class C and its subclass S, and give it an S, it will always use the S specialization rather than the C version, and more generally will use the most specific extension that applies to the run-time type of an object, then you can extend the protocol to Object and have the Object version test for an array, handle that case generically, and throw an exception otherwise.

You could also petition for clojure to be amended to add dummy types for "x-dimensional arrays", "arrays of foo", and "x-dimensional arrays of foo" generally, so one could put something in extend-protocol to extend it to all arrays of (ultimately) doubles or all three-dimensional arrays; but clojure itself changes relatively slowly, so you'd likely have to wait a year or two, if it ever did get done.





--
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@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+unsubscribe@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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



Reply all
Reply to author
Forward
0 new messages