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

Reply via email to