2014年9月30日火曜日

開発環境

計算機プログラムの構造と解釈[第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.を解いてみる。

その他参考書籍

問題 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 コメント:

コメントを投稿