Is it possible to implement set-car! and set-cdr! portably as macros using set! in Scheme? Or would this require special access to the underlying storage system?
I’m asking because I’m implementing my own Scheme interpreter, and I’d like to have as much as possible out in scheme code.
My first attempt on set-cdr! was:
(define-syntax set-cdr!
(syntax-rules ()
((set-cdr! location value)
(set! location (cons (car location) value)))))
This mostly works, but not for circular lists:
#; mickey> (define x (list 1 2))
#; mickey> x
(1 2)
#; mickey> (set-cdr! x x)
#; mickey> x
(1 1 2)
Wrapping the macro body in let did not help me either, because when I do (set! (cons (car location) value), then value has already been evaluated to be '(1 2).
In
the expression
(cons (car location) value)allocates a new pair.The purpose of
set-cdr!is to mutate an existing pair.So implementing
set-cdr!does require “special” access to the underlying storage.