2009/3/26 Konrad Hinsen <[email protected]> > > On 26.03.2009, at 14:59, Rich Hickey wrote: > > > Plus the inability to dispatch on other than class or eql, the > > inability to superimpose another taxonomy without redefining the > > class, the inability to have multiple independent taxonomies... > > The ability to have multiple taxonomies is indeed very useful in my > (limited) experience. > > > One is left-to-right argument order precedence, which roughly > > translates to vector precedence in Clojure (although the mapping to a > > vector need not follow arg order). > > I am not sure I'd want such a precedence. If I dispatch on several > arguments, their role is sometimes symmetric, sometimes not, and > where it is not, it is not necessarily the first argument that takes > precedence. > > However, what I wished I had on some occasions is a way to specify a > sequence of dispatching values as a result of the dispatch function. > For example, in a two-argument dispatch, I'd like to be able to write > something like > > (defmulti foo > (fn [x y] > (let [tx (type x) ty (type y)] > (list [tx ty] (cond (isa? tx ty) ty (isa? ty tx) tx :else #{tx > ty}))) > > with the result of calling a method for [tx ty] if available and one > of tx/ty/#{tx ty} otherwise. Without such an option, I sometimes have > to write several methods with an identical implementation but > different dispatch signatures. > > One way to make this and other generalizations possible would be to > have access to the multimethod's implementation list (and perhaps > preference order) in the dispatch function. > > > What I like about preference declarations is that you are > > acknowledging a definite ambiguity in a pure derivation hierarchy > > rather than poisoning the notion of hierarchy with directionality. > > What I like about them is that an ambiguity often points to a design > problem that should better be fixed than circumvented. > > > That said, perhaps the preference specifications at the method level > > aren't as reusable/convenient as preferences declared at another level > > or somewhere else. > > How about a preference function on each multimethod, along with the > dispatch function? One could then easily use one such function for > several multimethods. But what I suggested above (access to the > dispatch signatures and preferences in the dispatch function) should > be even more general.
I wanted to write something along those lines, but you Konrad did this better than I could have done :-) Though I don't have any concrete need currently: Am I the only one to have the feeling that the current functionalities provided by multimethods are too tied with the idea that the dispatching will be based on type hierarchies ? I think the current implementation closes the door to a lot of possibly interesting experiments/applications, because, as Konrad said, both the way the mechanism of discovering candidate methods, and the way to disambiguing them is somewhat hardcoded for a certain vision of type hierarchies. The current implementation, while maybe a good default (I don't have strong arguments against or pro for saying it is the right default mechanism) could certainly be just an implementation of a redefinable more generic solution. The way I understand it, the algorithm for discovering candidate methods is 1- compute a value from the arguments of the call, 2- and then determine for each method's declared dispatch-value if it is a relevant candidate Why not make the behavior of 2- user redefinable in the defmulti declaration ? Such a method could have the following definition : (fn [computed-value dispatch-values]) This method could return either nil (then a method with a default dispatch-value would be searched as usual), either a list of candidate dispatch-values (no requirement on the order of the returned values, this would be the job of the disambuating method). And the way I understand it, the algorithm for disambiguating candidate methods is 1- call a method that will apply an algorithm only based on deterministic relations between known-to-the-implementer-or-user existing methods. Why not make this 1- behavior just a "default" behaviour, and let the possibility for the user to totally use another one, by passing it to the defmulti declaration as a function : (fn [computed-value candidate-values]) (I'm not sure computed-value is interesting here, though, but maybe better have it than not) This method could return an ordered list of candidates. a) if the list is empty, then prefer-method will be called in a last resort b) else the first item of the list is the method to dispatch to. And the rest of the list could be passed to the method in a non intrusive way (could it be via rebinding a global ?) Thanks if you read past through this :-) And I'll be happy to see comments on this one. This really reflects what I had in mind for some time, so if I'm wrong in certain (or totally) areas, I'll be happy to learn from my own errors :-) -- Laurent > > > Konrad. > > > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---
