是否可以在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)
。
答案 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)