可以开车!和set-cdr!被实现为宏?

时间:2012-07-25 21:36:14

标签: lisp scheme metaprogramming abstract-syntax-tree

是否可以在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)时,value已被评估为'(1 2)

3 个答案:

答案 0 :(得分:4)

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

表达式(cons (car location) value)分配对。

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

因此,实施set-cdr!确实需要对基础存储进行“特殊”访问。

答案 1 :(得分:2)

这是一个实施Cons,Car,Cdr,Set-car的例子!和Set-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)

答案 2 :(得分:1)

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

因为你似乎在Scheme中实现了Scheme的实现,所以我会使用set-car!/ set-cdr!在解释器中实现它或根本没有实现它们。我会开始使用define,if,quote,pair?,eq?,cons,car和cdr(类似于The roots of LISP,但更多的schemish)来开始一个基本的最小实现,然后进一步增强它。

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

(define odds (list 1 3 5 7 9 11))
(set-car! (cddr odds) #f)
odds
===> (1 3 #f 7 9 11)