DanLebrero
DanLebrero

Reputation: 8593

Clojure idiomatic get-and-set function

Is there a more idiomatic/readable way of writing a get-and-set function in Clojure than:

(def the-ref (ref {}))

(defn get-and-set [new-value]
  (dosync
    (let [old-value @the-ref]
     (do
       (ref-set the-ref new-value)
       old-value))))

Upvotes: 3

Views: 187

Answers (1)

Arthur Ulfeldt
Arthur Ulfeldt

Reputation: 91554

for the simple cases I tend to see this operation used directly instead of wrapped in a function:

hello.core> (dosync (some-work @the-ref) (ref-set the-ref 5))
5

In this case dosync generally serves as the wrapper you are looking for. within the dosync This is significant because dosync composes nicely with other transactions and makes the bounds of the transaction visible. If you are in a position where the wrapper function can completely encapsulate all the references to the ref then perhaps refs are not the best tool.

A typical use of refs could look more along these lines:

(dosync (some-work @the-ref @the-other-ref) (ref-set the-ref @the-other-ref))

The need to wrap it is rare because when ref's are used they typically are use in groups of more than one ref because coordinated changes are required by the problem at hand. In cases where their is just one value then atoms are more common.

Upvotes: 2

Related Questions