On Mar 27, 2009, at 9:25, Mark Engelberg wrote: > I think I've answered at least part of my own question. This is the > simplest ambiguous case I've found: > > a b > | | > ---------- > | > c
Indeed. An ambiguous situation can occur whenever the type hierarchy graph is not a tree. Since it takes at least three nodes to make a graph that is not a tree, your example is the simplest one possible. > So if I understand correctly, the crux of the problem is that this > preference information is not part of the actual derive hierarchy. That is one way to put it, but I think there are other possible solutions than putting the preference information into the hierarchy. > One cost seems to be that if an outside user wants to write a new > method on this very same type hierarchy, he can only do it if he knows > how the types are derived from one another inside the library so that > he can restate all the necessary precedences with appropriate > prefer-method calls on his own new method. That could be avoided with a set of utility functions/macros for placing types into a hierarchy and for defining multimethods. These utility functions could take care of adding prefer-method calls as necessary. Of course, if this is a frequent need, explicitly language support would be preferable, but at least that would be a way to experiment with design options to figure out what works best. > Now, as an external user, I know nothing about where test-prefer on > ::c gets its behavior. Obviously, I have to disambiguate between > whether test-prefer chooses ::c over ::e, so I may try something like > this: > (prefer-method test-prefer ::c ::e) > > But this will not work. I still get an error saying I need to > disambiguate between ::a and ::e. And not knowing anything about ::a, > I could be very confused, and not know how to provide this > information. True. It would be nice if prefer-method could itself figure out that ::a provides the implementation for ::c. But again that functionality can be added with utility functions, as the hierarchy can be explored using the functions parents, ancestors, and descendants. > Considering how complex the situation can get with single dispatch, I > imagine it gets even more complex in multiple dispatch situations. In > the multimethods example at clojure.org/multimethods, an example is > given of disambiguating between [::shape ::rect] and [::rect ::shape]. > But again, if you're writing the bar method from outside of the > library which defines ::shape and ::rect, you might not even know > which is more specific. It might be easier to choose a strategy, such > as more specific on the leftmost taking precedence, than to know the > details of how the various types in the library interact. I am not so sure about this. I wonder if there is a real-life use case where a client library would need to solve dispatching issues on types in another library about which it doesn't know anything. If there isn't, the problem is not relevant, and if there is, I'd like to see a demonstration that something like left-to-right precedence is indeed a reasonable default. On the other hand, I would definitely like to be able to implement left-to-right precedence myself on top of Clojure's multimethods, and it seems that at the moment this is not possible. Konrad. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---