SICP問題4.28

また二週間ぶり。w

evalはapplyに渡す前に演算子を評価するのに、演算子の値を強制するため、evalでなくactual-valueを使う。この強制の必要性を示す例をあげよ、という問題。

パラメータで手続きを受け取る手続き f を考えてみる

(define (f g) (g 10))

これに渡す手続き test-proc を以下のように定義する

(define (test-proc x) (* x 10))

この時the-global-environmentではf, test-procは以下のように登録されている

;; test-proc
(procedure (x) ((* x 10)) #0#)
;; f
(procedure (g) ((g 10)) #0#)

以下の要領に f を実行してみる

(f test-proc)

apply の引数が actual-value の場合の実行結果は以下のようになる

;;; L-Eval input:
(f test-proc)

;;; L-Eval value:
100

apply の引数を actual-value でなく eval に変更した場合の実行結果は以下のようになる

;;; L-Eval input:
(f test-proc)
*** ERROR: Unknown procedure type -- APPLY (thunk test-proc #0=(((test-proc f false true car cdr cons null? = + - *) (procedure (x) ((* x 10)) #0#) (procedure (g) ((g 10)) #0#) #f #t (primitive #<subr car>) (primitive #<subr cdr>) (primitive #<subr cons>) (primitive #<subr null?>) (primitive #<subr =>) (primitive #<subr +>) (primitive #<subr ->) (primitive #<subr *>))))
Stack Trace:
_______________________________________
  0  (eval exp env)
        At line 94 of "C:/home/tmurata/scheme/4.Z_Delay.scm"
  1  (actual-value input the-global-environment)
        At line 690 of "C:/home/tmurata/scheme/4.Z_Delay.scm"

原因はエラーメッセージのとおり。
fを評価する際(applyでextend-environmentする際)に引数の遅延(thunk化)を行うが、evalではthunkの評価が出来ないためエラーとなる。