"All other invocations return the first calculated value." I fail to spot the part of your function where you keep this promise. >From what I can tell, your function would return nil on all but the first invocation.
I think you forgot to write "@result" in the else case in your last if clause. On Mon, Jan 26, 2009 at 9:32 PM, Stuart Halloway <[email protected]> wrote: > > Lancet's runonce function needs to wrap a function with runs-only-once > semantics, *and* make subsequent callers wait for the return value > before proceeding. There was a thread on this last November where Rich > explained several approaches > (http://groups.google.com/group/clojure/msg/406be93eb0a226aa > ). > > None of those approaches quite fit what Lancet needs. However, this > locking approach works (I think): > > (defn runonce > "Create a function that will only run once. All other invocations > return the first calculated value. The function *can* have side > effects, > and calls to runonce *can* be composed. Deadlock is possible > if you have circular dependencies. > Returns a [has-run-predicate, reset-fn, once-fn]" > [function] > (let [sentinel (Object.) > result (atom sentinel) > reset-fn (fn [] (reset! result sentinel)) > has-run-fn (fn [] (not= @result sentinel))] > [has-run-fn > reset-fn > (fn [& args] > (if (= @result sentinel) > (locking sentinel > (if (= @result sentinel) > (reset! result (function))))))])) > > Is this an example where locking is reasonable, or is there a better > Clojurish way? Your problem is inherently dealing with mutual exclusion. I think locking is appropriate. However, I think your double-check scheme, while safe, is of limited value. Uncontended locks, as would be the case in lancet, are pretty cheap. > > Stuart > > > > -- Venlig hilsen / Kind regards, Christian Vest Hansen. --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
