6章に出てきた value が再登場だ。value の定義は次のとおりだった(補助関数の定義は省略している)。
(define value (lambda (nexp) (cond ((atom? nexp) nexp) ((eq? (operator nexp) (quote e+)) (o+ (value (1st-sub-exp nexp)) (value (2nd-sub-exp nexp)))) ((eq? (operator nexp) (quote e*)) (o* (value (1st-sub-exp nexp)) (value (2nd-sub-exp nexp)))) (else (o^ (value (1st-sub-exp nexp)) (value (2nd-sub-exp nexp)))))))
4つある cond の質問と値のうち、最初のを別にすれば3つともよく似ている。違うのは演算子とそれに対応する関数だけだ。そこで、演算子(演算子はアトムであることに注意)から関数に変換する関数を書いてやれば、上の定義を簡単化することができる。
変換する関数 atom-to-function はこうだ。
(define atom-to-function (lambda (o) (cond ((eq? o (quote e+)) o+) ((eq? o (quote e*)) o*) (else o^))))
これを使って、簡単化した value はこうなる。補助関数も含めて全体を示す。
(use mymodule) (define 1st-sub-exp (lambda (aexp) (car (cdr aexp)))) (define 2nd-sub-exp (lambda (aexp) (car (cdr (cdr aexp))))) (define operator (lambda (aexp) (car aexp))) (define atom-to-function (lambda (o) (cond ((eq? o (quote e+)) o+) ((eq? o (quote e*)) o*) (else o^)))) (define value (lambda (nexp) (cond ((atom? nexp) nexp) (else ((atom-to-function (operator nexp)) (value (1st-sub-exp nexp)) (value (2nd-sub-exp nexp))))))) (print (value '(e+ 3 8))) (print (value '(e+ (e* 3 6) (e^ 8 2))))
実行結果:
^o^ > gosh -I. value4.scm 11 82
うまくいった!