SICP 読み (195) 4.2.2 遅延評価の解釈系

今日もこつこつ現実トウヒ (何と

問題 4.33

なんかもの凄いボケをカマしてるような予感がするので実機で確認。

  ("4.33"
   ("example"
    (let ((env (extend-environment '(tmp) '(0) the-global-environment)))
      (eval '(define (cons x y)
	       (lambda (m) (m x y))) env)
      (eval '(define (car z)
	       (z (lambda (p q) p))) env)
      (eval '(define (cdr z)
	       (z (lambda (p q) q))) env)
      (assert-equal 'a (eval '(car '(a b c)) env))
      )
    )
   )

試験してみると以下のような出力 (一部のみ

Error occurred in example
*** ERROR: Unknown procedure type -- APPLY (a b c)

(a b c) が delay されて car の中で actual-value されてる訳か。では、とゆー事で

      (assert-equal 'a (eval '(car (quote (a b c))) env))

してみたのですが結果は同じ。当たり前か。car も cdr も手続きを渡してあげないとイケナい。単純に text-of-quotation 手続きを修正してあげれば良いだけなんだろうか。例えば list 手続きを上記の cons 対応にするんだったら以下か。

(define (list a . b)
  (if (null? b)
      '()
      (cons a (list (car b) (cdr b)))))

ええと、これはわし的評価器遅延評価版の中で define しねぇといかんのか。あ、ヤバい、これって踏み込んではイケナいエリアっぽい。てーか、cons と car と cdr は上記試験のように評価器の評価ループの中で定義すべきなのか、評価器の記述の中で定義すべきなのかが微妙。
後者前提であれば text-of-quotation 手続きは以下のように書けるはず。

(define (text-of-quotation exp)
  (define (list a . b)
    (if (null? b)
	'()
	(cons a (list (car b) (cdr b)))))
  (if (pair? exp)
      (list (car exp) (cdr exp))
      (cadr exp)))

駄目かなぁ。cons のみが手続きを戻すナニになってないと微妙か。てコトは以下??

(define (text-of-quotation exp)
  (define (make-cons a . b)
    (if (null? b)
	'()
	(lambda (m) (m a (make-cons (car b) (cdr b))))))
  (if (pair? exp)
      (make-cons (car exp) (cdr exp))
      (cadr exp)))

こうなってればええのかな。でも ' な quote の場合はこれでも駄目な気がする。てか list もこれ方式で書けるな。って駄目じゃん。ラストの a が行方不明になるぞ。

(define (text-of-quotation exp)
  (define (make-cons a . b)
    (if (null? b)
	(lambda (m) (m a '()))
	(lambda (m) (m a (make-cons (car b) (cdr b))))))
  (if (pair? exp)
      (make-cons (car exp) (cdr exp))
      (cadr exp)))

あるいは list はこうですか。

(define (list a . b)
  (if (null? b)
      (lambda (m) (m a '()))
      (lambda (m) (m (car l) (list (car b) (cdr b))))))

なんか微妙。試験は別途で。