Having thought a little about multiple inheritance when implementing Spinoza
I also ran into this problem. However at the time I wasn't hindered by
multifn dispatch as much as the fact that parents cannot be ordered (because
calling parents on a tag returns a set) as pointed out by Mark. I understand
Rich's point that hierarchies probably shouldn't be directional, but for the
sake of practicality why not allow the programmer to specify that a tag (or
even the whole hierarchy) should in fact have its relationships be ordered?
In general prefer-method seemed to me (I could be wrong) to be a last
attempt solution- when there is just no other way to resolve an ambiguity,
and this ambiguity is not of the hierarchy, but of multimethod dispatch. As
pointed out by Konrad & Rich, you can work around the limitation of
hierarchies right now with a lot of prefer-methods.  But as Mikel points
out, with current state of prefer-method you have to hunt through code to
find out where these prefers were made and for what reason and they assume
that you've already written your methods (this for me is the deal breaker).

In anycase my general feeling (in agreement with Mark) is that the problem
isn't with multifns but rather with how hierarchies are constructed.

So the achilles heel of hierarchies seems to be that when you call parents
(and related fns) on a tag you get a set - it has no order.  For single
inheritance hierarchies this is fine, but for multiple inheritance I think
this becomes a problem a very fast. Working on Spinoza, I realized I would
have to keep my own ordered list of parents in order to support left-right
precedence, basically keeping an ordered copy of the whole hierarchy. Again
prefer-method is only useful for fixing method-level ambiguities.  There's
no general way to say, type A always precedes type B without writing quite a
bit of explicit code (or hiding the problem away with macros).

Here's something that might kick of a dicussion to a proper solution (I am
sure there are some gaps in my logic), why not allow something like the
following?

;; allow control of how tags get introduced into the hierarchy
(def h (make-hierarchy :parents-fn fn1 :ancestors-fn fn2 :descendants-fn
fn3))

;; add a new parent insertion fn to a hierarchy
(add-parents-fn h fn4) ;; -> returns a new hierarchy with the parents fn
set, all parents sets are converted into vectors

;; add a new parent insertion fn to a hierarchy for a specific key, only the
parents of ::my-tag are converted into a vector
(add-parents-fn h fn4 ::my-tag)

;; a hierarchy fn might look something like the following
(defn my-parents-fn [parents new-key]
   (conj parents new-key))

If my thinking is correct this is pretty flexible. This doesn't break the
meaning of hierarchy for any existing code.  It doesn't change the signature
of multimethods.  Yet now a user can provide fns that sorts a hierarchy
anyway they please, and it doesn't even have to be the entire hierarchy.
 This code will probably live in one spot where anyone could look to
understand how the hierarchy is being constructed.  All high-level
precedence ambiguities can now be resolved by looking at the hierarchy.
 prefer-method does only what it was intended to do- resolve method level
ambiguity.

David

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