Reputation: 111
(def alice-height
(ref 3))
(def right-hand-bites
(ref 10))
(defn eat-from-right-hand []
(dosync
(when (pos? @right-hand-bites)
(alter right-hand-bites dec)
(alter alice-height #(+ % 24)))))
This code is from the book Living Clojure. In the book, the author also gave an example with alter replaced by commute. I'm wondering with the pos?
test at the beginning, can we really do this replacement?
Upvotes: 4
Views: 121
Reputation: 22684
No, replacing alter
with commute
when decrementing right-hand-bites
is not correct.
The intention of the conditional is apparently to prevent right-hand-bites
from becoming negative. The decrement is only valid under the assumption that right-hand-bites
won’t change until the end of the transaction. While, like alter
, commute
has its own snapshot view of the ref world, it will re-read and re-apply the commute function to the ref at commit time, and that would be a mistake in this program.
So, with commute
it is possible to commit a negative value to right-hand-bites
.
Either stick with alter
, or use ensure
instead of @
(though that makes the whole commute exercise rather pointless).
Upvotes: 1