Functional programming 在Scheme中编写自动记忆器。宏和包装器的帮助

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)))

在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)))
        (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))))))
它应该创建一个阶乘的记忆版本,而不是普通的慢速版本

我的问题是

  • memoize包装器工作不正常,它不调用memoized函数,而是调用原始函数
  • 我不知道如何在宏内部编写define。如何确保可以获得可变长度的参数和可变长度的主体?然后如何定义函数并使用memorizer将其封装

  • 非常感谢。

    这是我在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参数,或使用单个哈希表查找所有参数,这可能意味着一个负载非常重的表)。