> (setq a (stream-cons (expt 2 2) (stream-cons (expt 2 3) 'empty-stream))) (4 (LAMBDA NIL (STREAM-CONS (EXPT 2 3) 'EMPTY-STREAM))) > (stream-rest a) (8 (LAMBDA NIL 'EMPTY-STREAM)) > (stream-rest a) (8 (LAMBDA NIL 'EMPTY-STREAM)) > (stream-rest a) (8 (LAMBDA NIL 'EMPTY-STREAM)) > a (4 (LAMBDA NIL (STREAM-CONS (EXPT 2 3) 'EMPTY-STREAM)))のように,毎回8を計算していました. そこで,最初の節のmemo関数のように一度計算したらば 覚えてしまうという方法を考えます.
(defmacro encapsulate (form) `(let ((switch nil) (result nil)) #'(lambda () (if switch result (setf switch t result ,form)))))というように,encapsulateを定義すると, クロージャの中に計算をしたかどうかのスイッチと 計算結果が保存されます. このクロージャが評価される(expose)たびに スイッチが判定されることになります.