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