SICP 全笔记

Exercise 4.33. Ben Bitdiddle tests the lazy list implementation given above by evaluating the expression

(car '(a b c))

To his surprise, this produces an error. After some thought, he realizes that the ‘‘lists’’ obtained by reading in quoted expressions are different from the lists manipulated by the new definitions of cons, car, and cdr. Modify the evaluator’s treatment of quoted expressions so that quoted lists typed at the driver loop will produce true lazy lists.

我们已经使用了新的 cons car cdr 的表示方法但 quote 没有变化。这导致了新的 car 不能操作以前的 cons 构造出来的对象。

我们需要更改 text-of-quotation 得到的 text,如果这里的 text 是一个 pair,那么我们应该使用新的 eval,调用 cons 来构造这个 pair。

需要注意的是转化出的 cons 应该使用 quote 来保留原表的类型:

'(a b c)
;=> (cons (quote a) (cons (quote b) (cons (quote c) '())))

这里的思路与 cond->iflet->lambdalet*->let 等等思路是一样的:


(define (text-of-quotation exp env)
  (let ((text (cadr exp)))
    (if (pair? text)
        (eval (quote-list->cons text) env)
        text)))

;; convert a list to cons construction
(define (quote-list->cons lst)
  (cond ((null? lst) '())
        ((not (pair? lst)) lst)
        (else
         (list 'cons (list 'quote (car lst)) (quote-list->cons (cdr lst))))))