Hm, I wrote a reply yesterday figuring it would show up today (seeing as I 
accidentally double posted last time because it did not show up at once), 
but that reply seems to be lost.

I see what you mean now, I think. Seeing as you will have to build your 
hierarchies yourself you might try something like the following:

(defrecord Label [text])
(defrecord TextField [text])

(defmacro c-mix [orig o-args mixin m-args]
  `(with-meta
    (new ~orig ~o-args)
    {:mixin (new ~mixin ~m-args)}))

;; Extracting the mixin instance
(defn mixin [o]
  (:mixin (meta o)))

(defmulti render (fn [x] (or (class (:mixin (meta x)))
                                     (class x))))
(defmethod render TextField [x] (:text x))
(defmethod render Label [x] (str (:text (mixin x)) ": " (render (with-meta 
x {}))))

(def labelledtextfield (c-mix TextField "Foo" Label "Name"))
(def textfield (TextField. "Foo"))

(render textfield) ;=> "Foo"
(render labelledtextfield) ;=> "Name: Foo"

This will allow you to emulate dynamic mixin composition by using the c-mix 
macro which is like a constructor call that attaches an instance of the 
mixin object as meta data. I know you would like to avoid macros, but since 
it is not possible to instantiate an object from a function parameter I 
don't think you can avoid them entirely.

Ad-hoc hierarchies using derive might also combine well with this solution, 
but then you would have to stay away from defrecord and define your own 
types I think.

Regards,
 Matthias

-- 
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
Note that posts from new members are moderated - please be patient with your 
first post.
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