On 17.05.2009, at 21:24, Mark Engelberg wrote:

> I don't want to post my actual code here, so let's run with this
> *gravity* example based off of what Adrian posted as a simple
> illustration.

Here is another solution that I consider preferable to the use of  
load. It requires you to specify explicitly which vars you want to be  
replaceable (which I consider an advantage), but otherwise it is very  
simple to transform a piece of code into a reusable template. If you  
(and/or others) consider this useful, I'd be happy to add it to  
clojure-contrib.

Konrad.

; This would be in clojure-contrib
(ns deftemplate)

(use 'clojure.contrib.macro-utils)

(defmacro deftemplate [name params & forms]
   (let [param-map (for [p params] (list (list 'quote p) (gensym)))
        template-params (vec (map second param-map))
        param-map (vec (apply concat param-map))
        expansion (list 'list (list 'quote `symbol-macrolet) param-map
                        (list 'quote (cons 'do forms)))]
     `(defmacro ~name ~template-params ~expansion)))

; This would be the slightly modified version of the original namespace
(ns gravity)

(deftemplate/deftemplate grav-template [*gravity* say-grav]

   (defn halve-grav []
     (/ *gravity* 2.0))

   (defn mult-grav [x]
     (* *gravity* x))

   (defn print-grav-stats []
     (say-grav *gravity*)
     (say-grav (halve-grav))
     (say-grav (mult-grav 2))))

(def *gravity* 1.0)

(defn say-grav [grav]
   (prn "Gravity is:" grav))

; Note: it is important to give namespace-qualified symbols here,  
otherwise the symbol macro
; expansion gets into an infinite loop.
(grav-template gravity/*gravity* gravity/say-grav)


; This would be the cloned-then-modified namspace
(ns gravity-variation1)

(def *gravity* 0.38)

(defn say-grav [grav]
   (prn "Gravity on Mars is:" grav))

(gravity/grav-template gravity-variation1/*gravity* gravity- 
variation1/say-grav)

; This would be the namespace using the two previous ones
(ns consumer)

(gravity/print-grav-stats)
(gravity-variation1/print-grav-stats)


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