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