(sicp53)問題4.14,4.15

4.14

make-lambdaで取り付けられたtag'procedureを基底の処理系が評価する手段をもって無いためerrorになる。

以下詳しく

(記憶が確かなら)define、set!を使わない箇所では、副作用を利用していない。
なので、置き換えで評価される様子を表すことができる。
driver-loopを起動して、そこで"(map (lambda (x) (* x x)) '(1 2 3))"という式が渡されると、評価器は以下のように動作する。

mapが組み込み手続きの場合
(eval (map (lambda (x) (* x x)) '(1 2 3)) global-environment)
	;以下渡された式は<exp>と表記する
	;global-environmentは<ENV>で表す
;;aplication?でtrueになる

(@apply (eval (operator <exp>) <ENV>)
   (list-of-values (operands <exp>) <ENV>)))
;;左から評価される
	;operator=car

(@apply (eval 'map <ENV>)
   (list-of-values (operands exp) <ENV>))
;;evalでmapはvariable?でtrueになる
	;<map>はmapの手続き

(@apply (primitive <map>) (list-of-values (operands exp) <ENV>))
	;operands=cdr

;;list-of-valuesの引数が左から展開されてく
(@apply (primitive <map>) (list-of-values ((lambda (x) (* x x)) '(1 2 3))))

;list-of-valuesが展開されてく
(@apply (primitive <map>) (cons (eval (lambda (x) (* x x)) <ENV>)
    (list-of-values  ('(1 2 3)))))

;;lambda?でtrue以下に変わる
(@apply (primitive <map>) (cons ('procedure (x) (* x x) <ENV>)
    (list-of-values ('(1 3 3)))))

;;quoted?でtrueで最後にnilになって終了
(@apply (primitive <map>) (('procedure (x) (* x x) <ENV>) '(1 2 3)))

;;@applyの手続きが適用される
	;*ここでprimitive-procedure?でtrueになるので以下の用に置換される
(apply-primitive-procedure 
  (primitive <map>) (('procedure (x) (* x x)) <ENV>) '(1 2 3))

;;apply-primitive-procedureの処理が進む
(apply (primitive-implementation (primitive <map>)
       ('procedure (x) (* x x) <ENV>) '(1 2 3)))
	;このapplyはgaucheのapply
;;最終的には以下のような処理が呼ばれる
(map (procedure (x) (* x x) <ENV>) '(1 2 3))
;;procedureなんてもの(gaucheは)知らない>error
*** ERROR: invalid application: ((procedure (x) ((* x x)) (((car primitive #<s...

4.15

仮にhalts?が定義できるなら、(try try)の動作はどうなるか?という問題
halts?が定義すると仮定してみる。

(define (run-forever) (run-forever))

(define (try p)
  (if (halts? p p)
      (run-forever)
      'halted))
;;(halts? f x) ::= (f x)が停止するかどうか

halts?で渡した手続きが停止するのかどうか分かるとする。
halts?がnil以外の値を返すなら必ず手続きが停止するとする。
(try try)とした場合
(if (halts? try try))
という式に置き換えられる(多分、halts?とかは副作用を使っていない)

halts?がnil以外の値を返す場合、

(halts?は実行が停止すると判断した)しかし、後の(run-forever)から停止しない処理を実行する

halts?がnilを返した場合

(halts?は実効が停止しないと判断した)しかし、後の'haltedから返り値を返すことがわかる。
こんな感じで上の仮定とは矛盾してしまうので、halts?は定義できない。