4

是否可以在 Scheme中使用宏来实现set-car!set-cdr! 移植?set!或者这是否需要对底层存储系统进行特殊访问?

我之所以问,是因为我正在实现自己的 Scheme 解释器,并且我希望尽可能多地使用方案代码。

我的第一次尝试set-cdr!是:

(define-syntax set-cdr!
  (syntax-rules ()
    ((set-cdr! location value)
     (set! location (cons (car location) value)))))

主要适用,但不适用于循环列表:

#; mickey> (define x (list 1 2))
#; mickey> x
(1 2)
#; mickey> (set-cdr! x x)
#; mickey> x
(1 1 2)

包裹宏体let也对我没有帮助,因为当我这样做时(set! (cons (car location) value), thenvalue已经被评估为'(1 2).

4

3 回答 3

4

(set! location (cons (car location) value))

该表达式(cons (car location) value)分配一个的对。

的目的set-cdr!是改变现有的对。

因此,实施set-cdr!确实需要对底层存储的“特殊”访问。

于 2012-07-25T21:56:52.527 回答
2

下面是一个实现 Cons, Car, Cdr, Set-car 的例子!和设置-cdr!使用闭包。

(define (Cons x y)
  (lambda (message . val)
    (cond
      [(eq? message 'car) x]
      [(eq? message 'cdr) y]
      [(eq? message 'set-car!) 
       (set! x (car val))]
      [(eq? message 'set-cdr!) 
       (set! y (car val))]
      [else 'unknown-message])))

(define (Car pair)
  (pair 'car))

(define (Cdr pair)
  (pair 'cdr))

(define (Set-cdr! pair val)
  (pair 'set-cdr! val))

(define (Set-car! pair val)
  (pair 'set-car! val))

(define p (Cons 1 2))
(Car p)
(Cdr p)
(Set-car! p 3)
(Car p)
(Set-cdr! p 4)
(Cdr p)
于 2012-07-25T22:13:13.893 回答
1

基本上你可以实现set!没有 set!,但我认为你不能实现 set-car!/set-cdr! 没有突变对或模拟对(如soegaard的例子)

既然你似乎在 Scheme 中实现你的 Scheme,我会使用 set-car!/set-cdr! 在解释器中实现它,或者根本不实现它们。我会从 define, if, quote, pair?, eq?, cons, car 和 cdr (类似于LISP 的根,但更诡计)开始有一个基本的最小实现开始,然后进一步增强它。

无论如何..你的实现,如果你实现它应该能够做到这一点:

(define odds (list 1 3 5 7 9 11))
(set-car! (cddr odds) #f)
odds
===> (1 3 #f 7 9 11)
于 2012-08-04T01:36:53.323 回答