The attached patch to clojure.core implements an optional universal  
parent type for Clojure hierarchies and defines such a type for the  
global default hierarchy. With this patch applied, Clojure passes the  
test_clojure and test_contrib test suites in clojure.contrib. I also  
tested it with all my own code.

The changes in detail:

1) make-hierarchy now takes as an optional argument the root type of  
the hierarchy. It is stored under the key :root.

2) derive preserves the :root key in the hierarchy map.

3) global-hierarchy is created with :root as its root type. The use  
of an unqualified keyword is not a mistake: by using a type that  
derive would refuse it makes sure that no one can tamper with the  
root type in any way.

4) isa? returns true if its parent argument is the root type of the  
hierarchy, no matter what the argument child is. This puts the root  
type above everything, including Object.

These changes would already be sufficient to get the functionality I  
wanted for multimethods. However, for consistency I also modified  
parents, ascendants, and descendants to create the coherent view that  
the root type is every other type's parent:

5) parents adds the root type (if defined) to its result set for any  
argument except the root type.

6) ancestors adds the root type (if defined) to its result set for  
any argument except the root type.

7) descendants returns the set of all types in the hierarchy if its  
argument is the root type.

I added one more fix to this patch:

8) The docstring of defmulti now says that the optional hierarchy  
argument must be a var referring to a hierarchy, rather than the  
hierarchy itself.


Here is an example of what becomes possible with this patch:

(defmulti plus (fn [x y] [(type x) (type y)]))

(defmethod plus :default
   [x y]
   "default")

(defmethod plus [java.lang.Number java.lang.Number]
   [x y]
   "two numbers")

(defmethod plus [:root java.lang.Number]
   [x y]
   "x anything, y number")

(defmethod plus [java.lang.Number :root]
   [x y]
   "x number, y anything")

(plus 1 2)
(plus 'x 2)
(plus 1 "abc")
(plus 'x 'y)

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

Attachment: root-type.patch
Description: Binary data

Reply via email to