Hi, one way to do that is using extend.
(def defaults {fn1 (fn ...) fn2 (fn ...) fn3 (fn ...)}) (defrecord R1 [...]) (def R1-fns {fn1 (fn ...)}) (defrecord R2 [...]) (def R2-fns {fn2 (fn ...) fn3 (fn ...)}) (extend YourProtocol R1 (merge defaults R1-fns) R2 (merge defaults R2-fns)) Another way is the following macro: (defmacro defrecord-with-defaults [record fields & protocol-default-fns] (let [process-protocol (fn [[protocol defaults fns]] (let [defaults (when defaults (->> defaults resolve var-get (map (fn [[k f]] (vector k (cons (symbol (name k)) (next f))))) (into {})))] (list* protocol (->> fns (map #(array-map (-> % first name keyword) %)) (apply merge defaults) (map second))))) split-protocols (fn split-protocols [p-d-fs] (lazy-seq (when-let [[p d & fs] (seq p-d-fs)] (let [[fs next-p-d-fs] (split-with (complement symbol?) fs)] (cons [p d fs] (split-protocols next-p-d-fs))))))] `(defrecord ~record ~fields ~@(mapcat process-protocol (split-protocols protocol-default-fns))))) Usage: (def foo-defaults `{:bar (fn ([this# that#] nil)) :baz (fn [this# that#] nil)}) (defrecord-with-defaults R [a b] Foo foo-defaults (bar [this that] nil) Frob nil (frobnicator [this] nil)) Note: you have to syntax-quote the functions in the default map (as for definline). And you can have only one arity per function. Here the corresponding expansion: (clojure.core/defrecord FooImpl1 [a b] Foo (bar [this that] nil) (baz [this__711__auto__ that__712__auto__] nil) Frob (frobnicator [this] nil)) Sincerely Meikel -- 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