On Nov 8, 2008, at 10:23 PM, Stuart Halloway wrote:

>
> How about:
>
> (defn runonce
>   "Create a function that will only run its argument once."
>   [function]
>   (let [call-count (ref 0)]
>     (fn [& args]
>       (when (= 1 (dosync (alter call-count inc)))
>         (apply function args)))))

The counter occurred to me too. I don't think it's necessary though.  
What's important is that one thread "know" that it was the one that  
cause the "false" to "true" transition.

Regarding the value returned by dosync above, I'd believe it if  
someone told me that it could only return 1 to one thread, one time,  
guaranteed, but I've been wrong before in my reasoning about alter vs.  
commute regarding what's possible, so I'll have to give it more  
thought on correctness.

Here's perhaps a more basic "one shot" building block:

(defn once
   "Returns a function that returns v the first time it's called and
   nil every time after that"
   [v]
   (let [returned (ref false)]
     (fn []
       (dosync
        (when-not (ensure returned)
          (ref-set returned true)
          v)))))

--Steve


--~--~---------~--~----~------------~-------~--~----~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to