建议使用备忘录的方式是什么?

时间:2018-12-06 04:06:38

标签: clojure

我偶尔使用了memoize函数。通常采用以下形式:

(defn- sqrt-denom [iterations]
  (/ 1 (if (= iterations 0)
         2
         (+ 2 (sqrt-denom (dec iterations))))))

(def sqrt-denom (memoize sqrt-denom))

我假设在备注时重用函数名称是“适当的”。这是一个好习惯吗?还是应该对非记忆和记忆功能使用不同的名称?

2 个答案:

答案 0 :(得分:5)

我将永远不会重复使用顶级def的名称,尤其是在自引用时。两种选择:

(defn ^:no-doc sqrt-denom-impl [iterations]
  (/ 1 (if (= iterations 0)
         2
         (+ 2 (sqrt-denom (dec iterations))))))

(def sqrt-denom (memoize sqrt-denom-impl))

或更简单:

(def sqrt-denom
  (memoize (fn  [iterations]
    (/ 1 (if (= iterations 0)
           2
           (+ 2 (sqrt-denom (dec iterations))))))

答案 1 :(得分:2)

像艾伦·汤普森(Alan Thompson)一样,我经常使用(def sqrt-denom (memoize (fn ...))),但是将一个简单的defn拆分为deffn只是为了包裹后者是很尴尬的。语法转换使得很难在函数的已记忆版本和未记忆版本之间来回切换,memoize是使我希望Clojure具有类似Python装饰器的功能。

然后,最近我发现Clojure确实具有装饰器:

(defn sqrt-denom ...)

(alter-var-root #'sqrt-denom memoize)

这与您的示例非常相似,但是它避免了两个名称相同的变量的混淆,并且清楚地表明了作者的意图。现在,这是我记忆功能的首选方法。