"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
-~----------~----~----~----~------~----~------~--~---

Reply via email to