計算機プログラムの構造と解釈[第2版]
(翔泳社)
ハロルド エイブルソン (著) ジュリー サスマン (著)
ジェラルド・ジェイ サスマン (著)
Harold Abelson (原著) Julie Sussman (原著)
Gerald Jay Sussman (原著) 和田 英一 (翻訳)
開発環境
- OS X Mavericks - Apple(OS)
- Emacs (CUI)、BBEdit - Bare Bones Software, Inc. (GUI) (Text Editor)
- Scheme (プログラミング言語)
- Gauche (処理系)
計算機プログラムの構造と解釈[第2版](ハロルド エイブルソン (著)、ジュリー サスマン (著)、ジェラルド・ジェイ サスマン (著)、Harold Abelson (原著)、Julie Sussman (原著)、Gerald Jay Sussman (原著)、和田 英一 (翻訳)、翔泳社、原書: Structure and Interpretation of Computer Programs (MIT Electrical Engineering and Computer Science)(SICP))の4(超言語的抽象)、4.2(Scheme の変形 - 遅延評価)、4.2.2(遅延評価の解釈系)、評価器の修正、サンクの表現、問題 4.28.を解いてみる。
その他参考書籍
- Instructor's Manual to Accompany Structure & Interpretation of Computer Programs
- プログラミングGauche (Kahuaプロジェクト (著), 川合 史朗 (監修), オライリージャパン)
問題 4.28.
手続きを引数としてとる手続きを評価するときに、演算子の値を強制するため、evalではなくactual-valueを使う必要がある。
例として、
(define env the-global-environment) (define (inc n) (+ n 1)) (define (f g) (g 10)) (f inc)を評価する場合を考えてみる。
変数incの値は
(procedure (n) ((+ n 1)) env)変数fの値は
(procedure (g) ((g 10)) env)
evalを使用した場合。
(apply (eval (operator (f inc)) env) (operands (f inc)) env) (apply (eval f env) (inc) env) (apply (procedure (g) ((g 10)) env) (inc) env) (eval-sequence ((g 10)) (extend-environment (g) (list-of-delayed-args (inc) env) env)) (eval-sequence ((g 10)) (extend-environment (g) ((delay-it inc env)) env)) (eval-sequence ((g 10)) (extend-environment (g) ((thunk inc env)) env)) ;; extended-environmentに変数g, 値(thunk inc env)が登録されている (eval-sequence ((g 10)) extended-environment) (eval (g 10) extended-environment) (apply (eval g extended-environment) 10 extended-environment) (apply (thunk inc env) 10 extended-environment) ;; この評価で (thunk inc env)は、基本手続きでも合成手続きでもなく、エラーになる。
evalではなくactual-valueを使った場合
(apply (actual-value (operator (f inc)) env) (operands (f inc)) env) (apply (actual-value f env) (inc) env) (apply (force-it (eval f env)) (inc) env) (apply (force-it (procedure (g) ((g 10)) env)) (inc) env) (apply (procedure (g) ((g 10)) env) (inc) env) (eval-sequence ((g 10)) (extend-environment (g) (list-of-delayed-args (inc) env) env)) (eval-sequence ((g 10)) (extend-environment (g) ((delay-it inc env)) env)) (eval-sequence ((g 10)) (extend-environment (g) ((thunk inc env)) env)) ;; extended-environmentに変数g, 値(thunk inc env)が登録されている (eval-sequence ((g 10)) extended-environment) (eval (g 10) extended-environment) (apply (actual-value (operator (g 10)) extended-environment) (operands (g 10)) extended-environment) (apply (actual-value g extended-environment) (10) extended-environment) (apply (force-it (eval g extended-environment)) (10) extended-environment) (apply (force-it (thunk inc env)) (10) extended-environment) (apply (actual-value (thunk-exp (thunk inc env)) (thunk-env (thunk inc env))) (10) extended-environment) (apply (actual-value inc env) (10) extended-environment) (apply (force-it (eval inc env)) (10) extended-environment) (apply (force-it (procedure (n) ((+ n 1)) env)) (10) extended-environment) (apply (procedure (n) ((+ n 1)) env) (10) extended-environment) (eval-sequence (procedure-body (procedure (n) ((+ n 1)) env)) (extend-environment (procedure-parameters (procedure (n) ((+ n 1)) env)) (list-of-delayed-args (10) extend-environment) (procedure-environment (procedure (n) ((+ n 1)) env)))) (eval-sequence ((+ n 1)) (extend-environment (n) ((delay-it 10 extend-environment)) env)) (eval-sequence ((+ n 1)) (extend-environment (n) ((thunk 10 extend-environment)) env)) ;; extended-environmentに変数n、値(thunk 10 extend-environment)が追加される。 (eval-sequence ((+ n 1)) extended-environment2) (eval (+ n 1) extended-environment2) (apply (actual-value + extended-environment2) (n 1) extended-environment2) (apply (force-it (eval + extended-environment2)) (n 1) extended-environment2) (apply (force-it (primitive +)) (n 1) extended-environment2) (apply (primitive +) (n 1) extended-environment2) (apply-primitive-procedure (primitive +) (list-of-arg-values (n 1) extended-environment2)) (apply-primitive-procedure (primitive +) ((actual-value n extended-environment2) (actual-value 1 extended-environment2))) (apply-primitive-procedure (primitive +) (force-it (eval n extended-environment2)) (force-it (eval 1 extended-environment2))) (apply-primitive-procedure (primitive +) ((force-it (thunk 10 extend-environment)) (force-it 1))) (apply-primitive-procedure (primitive +) ((actial-value 10 extend-environment) 1)) (apply-primitive-procedure (primitive +) (force-it (eval 10 extend-environment)) 1) (apply-primitive-procedure (primitive +) ((force-it 10) 1)) (apply-primitive-procedure (primitive +) (10 1)) (apply-in-underlying-scheme (primitive-implementation (primitive +)) (10 1)) (apply-in-underlying-scheme + (10 1)) 11
確認。
入出力結果(Terminal(gosh), REPL(Read, Eval, Print, Loop))
$ ./error_lazy_evaluator_without_analyzer.scm ;;; L-Eval input: (define (inc n) (+ n 1)) ;;; L-Eval value: ok ;;; L-Eval input: (define (f g) (g 10)) ;;; L-Eval value: ok ;;; L-Eval input: (f inc) gosh: "error": Unknown procedure type -- APPLY (thunk inc #0=(((f inc false true car cdr cons null? exit = + - * /) (procedure (g) ((g 10)) #0#) (procedure (n) ((+ n 1)) #0#) #f #t (primitive #<subr car>) (primitive #<subr cdr>) (primitive #<subr cons>) (primitive #<subr null?>) (primitive #<closure exit>) (primitive #<subr =>) (primitive #<subr +>) (primitive #<subr ->) (primitive #<subr *>) (primitive #<subr />)))) $ ./lazy_evaluator_without_analyzer.scm ;;; L-Eval input: (define (inc n) (+ n 1)) ;;; L-Eval value: ok ;;; L-Eval input: (define (f g) (g 10)) ;;; L-Eval value: ok ;;; L-Eval input: (f inc) ;;; L-Eval value: 11 ;;; L-Eval input: (exit) $
0 コメント:
コメントを投稿