遅延評価


遅延評価というのは、とりあえず今は評価しないでおいて、 あとで必要になったときに評価する(call by need)という使い方をします。 delay (ひとまず評価しないでおいておく)と、 force (必要だから、まだ評価していなかったら評価して)のセットで使われます。 これをつかうことで、6. ラムダ式の練習問題 2 とおなじ事が出来ます。 以下は無限リストの例です。

;;; (infinite-list n) 
;;; n, n+1, ... という無限リストを返す
;;; cdr 部は、遅延評価が行われる

(define (infinite-list n)           
  (display "infinite-list:") (display n) (newline) ; 使われる度にdebug print
  (cons n
	(delay (infinite-list (+ n 1))))) ; cdr 部は遅延評価

;;; infinite-list の n番目の要素を取り出す関数
;;; cdr 部の取り出しに force を行う。

(define (infinite-list-nth inf-list n)
  (if 	(= n 0)
	(car inf-list)
	(infinite-list-nth (force (cdr inf-list)) (- n 1)))) ; cdr 部の取り出しは force
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

> (let* ((x (infinite-list 0))        ; x は 0 から始まる無限リスト
         (y (infinite-list-nth x 3))) ; x の 3 番目の要素を取り出す。
    (display "Val of y:")         ; y の値をコメント付きで表示
    (display y) 
    (newline)
    (infinite-list-nth x 5))      ; x の 5 番目の要素を取り出す
infinite-list:0      ; x の生成時に呼ばれた。
infinite-list:1      ; (infinite-list-nth x 3) により、cdr 部が force された
infinite-list:2      ; 以下繰り返しで、
infinite-list:3      ; 3 番目の要素が生成され、
Val of y:3           ; y: 3 がとりだされた。
infinite-list:4      ; 次に (infinite-list-nth x 5)が呼ばれ、force が繰り返されるが、
infinite-list:5      ; 始めてよばれた 4, 5 に対してのみ実際の評価がなされている
5                    ; で、返り値

99.10.7/ Tomio KAMADA: kamada@cs.kobe-u.ac.jp