【发布时间】:2018-09-17 21:23:04
【问题描述】:
在 Land of Lisp 的第 329 页,Conrad Barski 用以下示例代码解释了 memoization 技术
(let ((old-neighbors (symbol-function 'neighbors))
(previous (make-hash-table)))
(defun neighbors (pos)
(or (gethash pos previous)
(setf (gethash pos previous) (funcall old-neighbors pos)))))
这个想法很好:当我调用neighbors函数时,我将结果保存到一个哈希表中,这样下次调用neighbors时,我就可以使用相同的pos值进行查找结果无需再次计算。
所以我想知道,通过编辑和重新编译其源代码(在本书的第 314 页给出)将函数 neighbors 重命名为 old-neighbors 是否更容易。那么memoization的例子可以简化为
(let ((previous (make-hash-table)))
(defun neighbors (pos)
(or (gethash pos previous)
(setf (gethash pos previous) (funcall old-neighbors pos)))))
或者,通过预先将previous 转换为全局变量*previous-neighbors*,甚至转换为
(defun neighbors (pos)
(or (gethash pos *previous-neighbors*)
(setf (gethash pos *previous-neighbors*) (funcall old-neighbors pos))))
因此不需要关闭。
所以我的问题是:这样做的原因是什么?
我能想到的原因:
- 它具有指导意义,展示了使用闭包可以做什么(之前已经解释过),并提供了
symbol-function的示例。 - 即使在您不能或不可能更改
neighbors的源代码的情况下,此技术也适用。 - 我错过了一些东西。
【问题讨论】:
标签: common-lisp memoization land-of-lisp