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


> On Nov 8, 2008, at 8:31 PM, Stuart Halloway wrote:
>
>>
>> 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]))
>
> Since the deref of has-run is outside a transaction, I don't see
> anything here that prevents two threads from running function if
> they're trying to do it at roughly the same time.
>
> I think the following version accomplishes the core task of running
> just once and could be adapted to return the has-run ref as well:
>
> (defn runonce
>   "Create a function that will only run its argument once."
>   [function]
>   (let [has-run (ref false)]
>     (fn [& args]
>       (when
>           (dosync
>            (ensure has-run)
>            (when-not @has-run
>              (ref-set has-run true)))
>         (apply function args)))))
>
> I'd appreciate seeing corrections or simplifications of it.
>
> --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