Macros 函数/宏仅在参数从上次调用更改时执行函数体
这应该类似于Macros 函数/宏仅在参数从上次调用更改时执行函数体,macros,clojure,functional-programming,clojurescript,Macros,Clojure,Functional Programming,Clojurescript,这应该类似于记忆,但非常不同。虽然memoize应该与纯函数一起使用,但它通常有助于加速与IO相关的函数 我正在寻找的函数/宏的行为应该类似于高阶函数。它产生的功能应: 第一次调用时,它应该调用原始函数,并向其传递参数 记住:参数,返回值 第二次呼叫时 使用相同的参数:它应该返回已记忆的返回值 使用不同的参数:忘记最后一个参数和返回值,调用原始函数,记住当前参数和返回值 第n次调用时,始终将参数与上次调用进行比较,并按照上述方式进行操作 修改memoize的源代码就很容易做到这一点 (de
记忆
,但非常不同。虽然memoize应该与纯函数一起使用,但它通常有助于加速与IO相关的函数
我正在寻找的函数/宏的行为应该类似于高阶函数。它产生的功能应:
- 第一次调用时,它应该调用原始函数,并向其传递参数
- 记住:参数,返回值
- 第二次呼叫时
- 使用相同的参数:它应该返回已记忆的返回值
- 使用不同的参数:忘记最后一个参数和返回值,调用原始函数,记住当前参数和返回值
- 第n次调用时,始终将参数与上次调用进行比较,并按照上述方式进行操作
- 修改
memoize
的源代码就很容易做到这一点
(defn memo-one [f]
(let [mem (atom {})]
(fn [& args]
(if-let [e (find @mem args)]
(val e)
(let [ret (apply f args)]
(reset! mem {args ret})
ret)))))
(defn foo [x] (println "called foo") x)
(def memo-foo (memo-one foo))
然而,已经有一个灵活的备忘录库可以做到这一点
(require '[clojure.core.memoize :as memo])
(defn foo [x] (println "called foo") x)
(def memo-foo (memo/lru foo :lru/threshold 1))
这是一个仅使用clojure.core的版本。我从A.Webb的示例中借用了
foo
函数进行演示
(defn memoize-1
[f]
(let [previous (atom nil)]
(fn [& args]
(second
(swap! previous
(fn [[prev-args prev-val :as prev]]
(if (and prev (= prev-args args))
prev
[args (apply f args)])))))))
user> (defn foo [x] (println "called foo") x)
#'user/foo
user> (def memo-foo (memoize-1 foo))
#'user/memo-foo
user> (memo-foo 1)
called foo
1
user> (memo-foo 1)
1
user> (memo-foo 2)
called foo
2
user> (memo-foo 1)
called foo
1
这与memoize完全相同,只是它只记住一个参数->值对.nice,特别是当值已经被heldI意识到我需要一些完全不同的东西(自定义缓存策略)时,避免交换,但基本上我在实现之前就使用了它。附加问题:比较类型化数组的快速、高效内存的方法:)(是的,这些是我的参数,我重复使用它们以提高性能)。@skrat我建议将附加问题作为一个新问题,详细说明如何使用数组。如果您正在重用相同的阵列,那么答案很简单。
(defn memoize-1
[f]
(let [previous (atom nil)]
(fn [& args]
(second
(swap! previous
(fn [[prev-args prev-val :as prev]]
(if (and prev (= prev-args args))
prev
[args (apply f args)])))))))
user> (defn foo [x] (println "called foo") x)
#'user/foo
user> (def memo-foo (memoize-1 foo))
#'user/memo-foo
user> (memo-foo 1)
called foo
1
user> (memo-foo 1)
1
user> (memo-foo 2)
called foo
2
user> (memo-foo 1)
called foo
1