Finally started a GitHub repo just for this project.
http://github.com/swannodette/cljos/tree/master

The earlier version of course was very flawed/buggy.  OK start, but the
macros in it were written with little/no understanding about how symbols are
resolved into their namespaces in Clojure (or Lisp for that matter). If
anybody is interested at all please feel free to fork or to leave comments.
 In particular I found no way to capture the symbols and their true
namespaces without resorting to eval and some wacky macros.  That said, it
does indeed work.  defclassed structs always refer to the namespace in which
they were declared, and parents correctly reflect their originating
namespace as well.

New stuff:

(instance-of? my-platypus platypus)
(member-of? a-circle shape)

No need for tags.  The only time you need tags is when defining
multimethods.  There's no real clean way to get around this except
implementing a macro around defmethod, and I'm not really sure creating a
macro around defmethod is so hot.  The discussion earlier about multiple
hierarchies for multimethod, especially predicate support would solve this
cleanly.

defclass now returns the struct.  I've also been toying around with an
optional Smalltalk message based dispatch.  Note the special applym, a
special version of apply that first checks to see if a struct responds? to a
multimethod.  If not it checks to see if there is a proxy and forwards the
message with the args to proxy.  This could allow for some interesting
interactions.

(defclass my-spore-animal [platypus]
  (:third-eye true))

(defclass bacteria [object]
  (:digest-grass true))

(def my-spore (make-instance my-spore-animal))
(def my-parasite (make-instance bacteria))

(defmulti digest :tag)
(defmethod digest ::bacteria [obj]
  (println "Munch munch!"))

;; we can pass messages to a proxy class
(applym digest (assoc my-spore :proxy my-parasite)) ;; "Munch Munch!"


The most exciting thing however is multimethod reflection (many thanks to
Rich).  The following is all the code it takes to see all the multifns that
specializes a particular tag.  In fact, really it should check all the
ancestors of the tag as well in order and I'm open to suggestions on what
the best way to implement that would be.

(defn has-dispatch? [multifn tag]
  (not (= (tag (methods multifn))
  nil)))

(defn responds? [obj multifn]
  (has-dispatch? multifn (:tag obj)))

(defn is-multi? [metadata]
  (and (:tag metadata)
      (= clojure.lang.MultiFn (:tag metadata))))

(defn who-specializes-tag? [tag]
  (filter #(and (is-multi? (meta %))
(has-dispatch? (var-get %) tag))
  (flatten (map #(vals (ns-interns %)) (all-ns)))))

(defmacro who-specializes? [constructor]
  `(who-specializes-tag?
    (:class (meta (var ~(symbol (name constructor)))))))

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