On Lisp 復習
つづき(d:id:Nobuhisa:20080120:1200761083)
5.2 直交性
CL-USER 1 > (defvar *!equivs* (make-hash-table)) *!EQUIVS* CL-USER 2 > (defun ! (fn) (or (gethash fn *!equivs*) fn) ) ! CL-USER 3 > (defun def! (fn fn!) (setf (gethash fn *!equivs*) fn!) ) DEF! CL-USER 4 > (def! #'remove-if #'delete-if) #<Function DELETE-IF 2021134A> CL-USER 5 > (setq a '(1 2 3 4 5 6)) (1 2 3 4 5 6) CL-USER 6 > (setq a (funcall (! #'remove-if) #'oddp a) ) (2 4 6)
関係ないけど,equivsって何語・・・?(辞書とgoogleさんに聞いてみたけど良くわからず...
あと,!関数は本当ならマクロの方が効率的だと書いてあった。こんな感じになるのかな・・・
CL-USER > (defmacro !! (fn &rest args) (let ((f (or (gethash (symbol-function fn) *!equivs*) fn))) `(funcall ,f ,@args) )) !! CL-USER > (macroexpand '(!! remove-if #'oddp a)) (FUNCALL #<Function DELETE-IF 2021134A> (FUNCTION ODDP) A) T CL-USER > (setq a (!! remove-if #'oddp a)) (2 4 6 8 10)
マクロ初心者なのでやや苦戦した。。。マクロの章が楽しみ。
5.3 関数の値のメモ化
memoize.
CL-USER 1 > (defun memoize (fn) (let ((cache (make-hash-table :test #'equal))) #'(lambda (&rest args) (multiple-value-bind (val win) (gethash args cache) (if win val (setf (gethash args cache) (apply fn args)) ))))) MEMOIZE CL-USER 2 > (setq slowid (memoize #'(lambda (x) (sleep 5) x)) ) #<anonymous interpreted function 217029E2> CL-USER 3 > (time (funcall slowid 256)) Timing the evaluation of (FUNCALL SLOWID 256) User time = 0.000 System time = 0.000 Elapsed time = 5.000 Allocation = 14540 bytes 0 Page faults 256 CL-USER 4 > (time (funcall slowid 256)) Timing the evaluation of (FUNCALL SLOWID 256) User time = 0.000 System time = 0.000 Elapsed time = 0.001 Allocation = 812 bytes 0 Page faults 256
time関数便利だなぁ。