The defrunonce macro below works, creating a function that runs only  
once and tracking its run status in metadata.

Now, how do I write it without using eval?

(defn runonce
   "Create a function that will only run once, given a function. Returns
   a vector containing the function and the reference that tracks  
whether
   the function has been run."
   [function]
   (let [has-run (ref false)]
     [(fn [& args]
        (or @has-run
           ; TODO: think through semantics for parallel target invocation
           (do
             (apply function args)
             (dosync (ref-set has-run true)))))
      has-run]))

(defmacro defrunonce [sym doc & forms]
   "Defines a function with runonce semantics. Curren run status
   is kept in a reference under the :has-run metadata key."
   (let [[function has-run] (runonce (eval (concat (list 'fn [])  
forms)))]
     `(def ~(with-meta sym {:has-run has-run}) ~function)))



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to