Scrivendo un auto-memoizer nello Schema. Aiuto con la macro e un wrapper
-
21-08-2019 - |
Domanda
Sono di fronte un paio di problemi durante la scrittura di un auto-memoizer nello Schema.
Ho una funzione memoizer di lavoro, che creats una tabella hash e controlla se il valore è già calcolato. Se è stato calcolato prima di allora restituisce il valore altrimenti chiama la funzione.
(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)))))))
Ora voglio creare una funzione Memoize-wrapper in questo modo:
(define (memoize-wrapper function)
(set! function (memoizer function)))
E si spera di creare una macro denominata def-memo che definisce la funzione con il Memoize-wrapper. per esempio. la macro potrebbe espandersi a (memoizer (definire nome-funzione argomenti corpo ...) o qualcosa del genere.
In modo che io dovrei essere in grado di fare:
(def-memo (factorial n)
(cond
((= n 1) 1)
(else (* n (factorial (- n 1))))))
, che dovrebbe creare una versione memoized del fattoriale invece del normale un lento.
Il mio problema è che la
- Il Memoize-involucro non funziona correttamente, si pretende molto chiamare la funzione memoized ma la funzione originale.
- Non ho idea di come scrivere un definire all'interno della macro. Come faccio a fare in modo che posso ottenere gli argomenti della lunghezza variabile e corpo lunghezza variabile? Come faccio a indicare la funzione di e avvolgerla intorno al memoizer?
Grazie mille.
Soluzione
Questo è quello che uso nello schema 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)