Functional programming 在Scheme中编写自动记忆器。宏和包装器的帮助
在Scheme中编写自动回忆录时,我面临几个问题 我有一个有效的memoizer函数,它创建一个哈希表并检查值是否已经计算出来。如果之前已经计算过,则返回值,否则调用函数Functional programming 在Scheme中编写自动记忆器。宏和包装器的帮助,functional-programming,macros,scheme,racket,Functional Programming,Macros,Scheme,Racket,在Scheme中编写自动回忆录时,我面临几个问题 我有一个有效的memoizer函数,它创建一个哈希表并检查值是否已经计算出来。如果之前已经计算过,则返回值,否则调用函数 (define (memoizer fun) (let ((a-table (make-hash))) (λ(n) (define false-if-fail (λ() #f)) (let ((return-val (hash-ref a-table n false-if-fail)))
(define (memoizer fun)
(let ((a-table (make-hash)))
(λ(n)
(define false-if-fail (λ() #f))
(let ((return-val (hash-ref a-table n false-if-fail)))
(if return-val
return-val
(begin
(hash-set! a-table n (fun n))
(hash-ref a-table n)))))))
现在我想创建一个memoize包装函数,如下所示:
(define (memoize-wrapper function)
(set! function (memoizer function)))
并希望创建一个名为def memo的宏,该宏使用memoize包装器定义函数。宏可以扩展到(memoizer(定义函数名参数body…)或类似的东西
这样我就能做到:
(def-memo (factorial n)
(cond
((= n 1) 1)
(else (* n (factorial (- n 1))))))
它应该创建一个阶乘的记忆版本,而不是普通的慢速版本
我的问题是
非常感谢。这是我在PLT方案中使用的:
#lang scheme
(define (memo f)
(define mh (make-hash))
(lambda p
(hash-ref mh p (lambda ()
(hash-set! mh p (apply f p))
(hash-ref mh p)))))
(define-syntax-rule (defmemo (id . p) . body)
(define id (memo (lambda p . body))))
(provide defmemo)
哇。太棒了。你能简单地评论一下你的代码,特别是宏位吗。为什么有?你为什么提供?你真的需要应用吗?我是个新手。谢谢。在参数列表中,。表示以下变量绑定到多个东西。在宏中,p是一个参数列表,而不仅仅是一个参数(body是一个表达式列表)。在函数中,将p(一个参数列表)应用于函数f也需要apply。另请参见:哦,顺便说一句,注意记忆并不总是那么简单;您可能希望基于参数标识进行记忆(例如,使用
eq?
哈希表),或仅针对某些参数,或使用弱哈希表以避免内存泄漏等。此外,由于各种原因,上述解决方案可能会比较慢(例如使用rest参数,或使用单个哈希表查找所有参数,这可能意味着一个负载非常重的表)。