简体   繁体   中英

Can the alter be replaced with commute in the following Clojure code?

(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?

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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM