問題4.16 – SICP(計算機プログラムの構造と解釈)その188
2009年05月27日
問題4.16
a. lookup-variable-value に、値が *unassigned* の場合にエラーを返す処理を追加する。
(define (lookup-variable-value var env) (define (env-loop env) (define (scan vars vals) (cond ((null? vars) (env-loop (enclosing-environment env))) ((eq? var (car vars)) (if (eq? '*unassigned* (car vals)) (error "Unassigned variable -- LOOKUP-VARIABLE-VALUE" var) (car vals))) (else (scan (cdr vars) (cdr vals))))) (if (eq? env the-empty-environment) (error "Unbound variable" var) (let ((frame (first-frame env))) (scan (frame-variables frame) (frame-values frame))))) (env-loop env))
b. scan-out-defines 手続きを定義する。
(define (scan-out-defines body) (define (iter exp vars sets exps) (if (null? exp) (list (reverse vars) (reverse sets) (reverse exps)) (if (definition? (car exp)) (iter (cdr exp) (cons (list (definition-variable (car exp)) ''*unassigned*) vars) (cons (list 'set! (definition-variable(car exp)) (definition-value (car exp))) sets) exps) (iter (cdr exp) vars sets (cons (car exp) exps))))) (define (include-define? exp) (if (null? exp) #f (if (definition? (car exp)) #t (include-define? (cdr exp))))) (if (include-define? body) (let ((var-val-exp-list (iter body '() '() '()))) (list (cons 'let (cons (car var-val-exp-list) (append (cadr var-val-exp-list) (caddr var-val-exp-list)))))) body))
実行結果
;;; M-Eval input:
(define foo (lambda (x)
(define a 1)
(define b 2)
(* (+ a x) b)))
;;; M-Eval value:
ok
;;; M-Eval input:
(foo 7)
;;; M-Eval value:
16
;;; M-Eval input:
(define (f x)
(define (even? n)
(if (= n 0)
true
(odd? (- n 1))))
(define (odd? n)
(if (= n 0)
false
(even? (- n 1))))
(cond ((even? x) 'even)
((odd? x) 'odd)))
;;; M-Eval value:
ok
;;; M-Eval input:
(f 5)
;;; M-Eval value:
odd
;;; M-Eval input:
(f 6)
;;; M-Eval value:
even
c. scan-out-defines を組み込む適切な場所。
どちらに組み込んでもきちんと動作するが、procedure-body に組み込むと apply と user-print 手続きで呼ばれるのに対し、make-procedure に組み込めば eval の際のみに呼ばれるから make-procedure がよい。
と、思ったら、他の人の解答例では procedure-body に組み込んでいる例の方が多かった…
計算機プログラムの構造と解釈
posted with amazlet at 08.11.07
ジェラルド・ジェイ サスマン ジュリー サスマン ハロルド エイブルソン
ピアソンエデュケーション
売り上げランキング: 6542
ピアソンエデュケーション
売り上げランキング: 6542
