在Scheme中编写自动记忆器.帮助宏和包装

unj*_*nj2 5 macros scheme functional-programming 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)))
        (if return-val
            return-val
            (begin
              (hash-set! a-table n (fun n))
              (hash-ref a-table n)))))))
Run Code Online (Sandbox Code Playgroud)

现在我想创建一个memoize-wrapper函数,如下所示:

(define (memoize-wrapper function)
  (set! function (memoizer function)))
Run Code Online (Sandbox Code Playgroud)

并希望创建一个名为def-memo的宏,它使用memoize-wrapper定义函数.例如.宏可以扩展为(memoizer(定义函数名称参数body ...)或类似的东西.

所以我应该能够做到:

(def-memo (factorial n)
  (cond
    ((= n 1) 1)
    (else (* n (factorial (- n 1))))))
Run Code Online (Sandbox Code Playgroud)

这应该创建一个memialized版本的阶乘而不是正常的慢阶段.

我的问题是

  1. memoize-wrapper工作不正常,它不会调用memoized函数而是调用原始函数.
  2. 我不知道如何在宏内部编写一个定义.我如何确保我可以获得变量长度参数和可变长度体?然后我如何定义函数并用memoizer包装它?

非常感谢.

Jav*_*ier 6

这是我在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)
Run Code Online (Sandbox Code Playgroud)

  • 哦,顺便说一句,请注意记忆并不总是那么简单;您可能想根据参数标识(例如,使用 `eq?` 哈希表)或仅根据某些参数进行记忆,或使用弱哈希表来避免内存泄漏等。此外,上述解决方案可能很慢出于各种原因(例如使用休息参数,或用于查找所有参数的单个哈希表,这可能意味着非常加载的表)。 (2认同)