首页 > 解决方案 > 在以下 Clojure 代码中,alter 可以替换为 commute 吗?

问题描述

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

此代码来自 Living Clojure 一书。在书中,作者还举了一个将alter替换为commute的例子。我想知道pos?一开始的测试,我们真的可以做这个替换吗?

标签: concurrencyclojure

解决方案


不,当递减不正确时替换alter为。commuteright-hand-bites

条件句的意图显然是为了防止right-hand-bites变成否定的。right-hand-bites只有在交易结束前不会改变的假设下,减量才有效。虽然 likealtercommute自己的 ref 世界快照视图,但它会在提交时重新读取 commute 函数并将其重新应用到 ref ,这在该程序中将是一个错误。

因此,commute可以将负值提交给right-hand-bites.

要么坚持使用alter,要么使用ensure代替@(尽管这使得整个通勤练习变得毫无意义)。


推荐阅读