我偶尔使用了memoize
函数。通常采用以下形式:
(defn- sqrt-denom [iterations]
(/ 1 (if (= iterations 0)
2
(+ 2 (sqrt-denom (dec iterations))))))
(def sqrt-denom (memoize sqrt-denom))
我假设在备注时重用函数名称是“适当的”。这是一个好习惯吗?还是应该对非记忆和记忆功能使用不同的名称?
答案 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
拆分为def
和fn
只是为了包裹后者是很尴尬的。语法转换使得很难在函数的已记忆版本和未记忆版本之间来回切换,memoize
是使我希望Clojure具有类似Python装饰器的功能。
然后,最近我发现Clojure确实具有装饰器:
(defn sqrt-denom ...)
(alter-var-root #'sqrt-denom memoize)
这与您的示例非常相似,但是它避免了两个名称相同的变量的混淆,并且清楚地表明了作者的意图。现在,这是我记忆功能的首选方法。