On the subject of per defmulti hierarchies: The recent CLJOS thread got me thinking about this problem again. While allowing per-multimethod hierarchies solves a large number problems, I think it might be lacking for a class of needs. I think I have solution that can provide for multiple hierarchies and meet this larger class to which I allude. Allow me to provide an illustration. Say I have a step-wise mathematical function. From less than or equal to zero, return zero. From more than zero to less than equal to five, return the value. Above 5, square the value.
I could implement that as multimethod: (defmulti stepwise (fn [n] (cond (>= 0 n) :zero (and (> n 0) (< n 5)) :zero-five :else :above-five))) (defmethod stepwise :zero [_] 0) (defmethod stepwise :zero-five [x] x) (defmethod stepwise :above-five [x] (* x x)) I've left an intentional programming error in to show how easy it is to make an error with such (cond ...) based dispatch. Yuck. But there is a better way. What if I could supply my own function to decide which key matched the multimethod (not what the key is for the value, but how the key maps to a multimethod). Currently all we have is isa?, but if this were only the default? My example might look something like: (defmulti stepwise identity <=) (defmethod stepwise 0 [_] 0) (defmethod stepwise 5 [n] n) (defmethod stepwise :default [n] (* n n)) (prefer-method stepwise 0 5) ; since -1 < 0 and -1 < 5 I find this much cleaner, and the subtle error above was been eliminated. And if I want to add another case, its not too hard (though the number of prefer-methods might increase exponentially). This is a rather trivial case, but I think it makes the need clear: per-multi comparison functions. For multiple hierarchies, this would be a common idiom: (defmulti mymulti dispatch-function (fn [object-key method-key] (isa? *my-hiearchy* object-key method-key)) A user could use a ref or atom as needed, no special casing in the Clojure code. What do people think? -Mark On Jan 7, 2009, at 10:44 AM, Meikel Brandmeyer wrote: > Hi Rich, > > Am 07.01.2009 um 17:10 schrieb Rich Hickey: > >> Thanks Meikel. I have a couple of points: >> >> First, making derive and underive act on vars instead of the >> hierarchies directly is not good - it reduces the generality >> needlessly. Good practice is to make pure fns, then do the reference >> part, not mix the two. >> >> Second, there's no reason to bind MultiFn to Var - any IRef will do. >> Then people can put their hierarchies in Atoms/Refs or whatever. >> >> Third, I don't see the need for defhierarchy at this point. > > Ok. My problem is, that passing the hierarchy directly > doesn't allow adding further derivations. The only idea > I had, was to use Vars. I didn't like the idea, but I > couldn't come up with another one. The solution is again > an abstraction: IRef. Changing (un)derive and adding > defhierarchy, was just some try to help the user with > the limitations of this approach. > > But (dosync (alter ref-to-hierarchy derive ::Foo ::Bar)) > works perfectly. :) Much cleaner indeed. This shows > again: ugly solutions and special cases are a sign, > that one does it wrong... > > Please find attached another patch going for IRef instead > of Var directly. And without the other cruft. > > Sincerely > Meikel > > <issue-8b.diff> - Mark Fredrickson mark.m.fredrick...@gmail.com http://www.markmfredrickson.com --~--~---------~--~----~------------~-------~--~----~ 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 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 -~----------~----~----~----~------~----~------~--~---