next up previous
Next: 8.3 2引数以上の関数の場合 Up: 8 クロージャによる結果記憶型関数(memoization)の実現 Previous: 8.1 結果記憶手続きへの変換手続き

8.2 結果記憶型関数を定義するマクロの定義

以上のことから,fibを定義するときに,defunを 使わずに,defun*のような定義文を使えば 自動的に計算結果記憶関数を実現してくれる マクロを作ることを考えて見ます.

(defun memoize (fn-name)
  (setf (symbol-function fn-name)
        (memo (symbol-function fn-name))))

(defmacro defun* (fn args &rest body)
  `(memoize (defun ,fn ,args ,@body)))
または,

(defmacro defun* (fn args &rest body)
  `(let ((fn-name (defun ,fn ,args ,@body)))
     (setf (symbol-function fn-name)
           (memo (symbol-function fn-name)))))
というような関数定義マクロdefun*を用いることで,記憶型の関数を定義でき るようになります.

(defun* fib* (n)
      (if (< n 2) 1
          (+ (fib* (1- n)) (fib* (- n 2)))))
> 
> (time (fib* 19))
cpu time (non-gc) 100 msec user, 17 msec system
cpu time (gc)     0 msec user, 0 msec system
cpu time (total)  100 msec user, 17 msec system
real time  127 msec

6765 

;;; clispの場合
[34]> (time (fib* 19))

Real time: 0.0 sec.
Run time: 0.0 sec.
Space: 320 Bytes
6765
ここまでの例では,fibのように引数がひとつの関数の ものでした.そこで,複数の引数をもつものでも対応が とれるようにします.

generated through LaTeX2HTML. M.Inaba 平成18年5月6日