Clojure 建议使用memoize的方法是什么?

Clojure 建议使用memoize的方法是什么?,clojure,Clojure,我偶尔使用memoize函数。通常采用以下形式: (defn- sqrt-denom [iterations] (/ 1 (if (= iterations 0) 2 (+ 2 (sqrt-denom (dec iterations)))))) (def sqrt-denom (memoize sqrt-denom)) 我认为在记忆时重用函数名是合适的。这是一种好的做法吗?或者我应该为非记忆函数和记忆函数使用不同的名称吗?我不会重复使用顶级def的名称

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

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

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

我认为在记忆时重用函数名是合适的。这是一种好的做法吗?或者我应该为非记忆函数和记忆函数使用不同的名称吗?

我不会重复使用顶级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))))))

像艾伦·汤普森一样,我经常使用def sqrt denom memoize fn…,但是将一个简单的defn拆分成def和fn只是为了包装后者是很尴尬的。语法转换使得函数的memoize和unmemoize版本之间很难来回切换,而memoize是一个让我希望Clojure拥有类似Python装饰器的函数

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

(defn sqrt-denom ...)

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

这与您的示例非常相似,但它避免了将两个变量命名为同一事物的混淆,并且清楚地说明了作者的意图。现在,这是我记忆函数的首选方法。

您有什么特别的理由给未记忆的版本命名吗?def sqrt denom MEMORIZE fn[迭代]…但我会小心永久记住顶级def。如果您的程序运行很长时间,并且该函数暴露于许多不同的输入,那么记忆映射可能会变得巨大。当然,在处理记忆问题时,这是一种折衷,但我首先要确保本地的记忆版本是不够的。尽管如此,我认为你的技术没有任何问题,Clojure docs中的类似例子:是的,例如Leiningen使用了这种技术。在开发过程中,非momized defn非常方便。