将项目添加到计划中的领导队列

adding items to a headed queue in scheme

我试图理解以下用于将项目添加到方案中的带头队列的代码。代码取自 The Scheme Programming Language (Link to the chapter).

(define make-queue
  (lambda ()
    (let ((end (cons 'ignored '())))
      (cons end end)))) 

(define putq!
  (lambda (q v)
    (let ((end (cons 'ignored '())))
      (set-car! (cdr q) v)
      (set-cdr! (cdr q) end)
      (set-cdr! q end))))

我不明白这段代码如何同时修改队列和头部。队列 (car q) 根本不会在此函数中调用。如果我手动执行这些步骤,一个接一个,我可以看到修改 (cdr q) 同时修改 (car q) 但我不知道为什么。这是我手动添加项目的终端输出(加载上述代码后):

(define myq (make-queue))
(display myq) => ((ignored) ignored)
(set-car! (cdr myq) 'a)
(display myq) => ((a) a)
(set-cdr! (cdr myq) (cons 'ignored '()))
(display myq) => ((a ignored) a ignored)
(set-cdr! myq (cons 'ignored '()))
(display myq) => ((a ignored) ignored)

特别让我费解的是定车!和第一个 set-cdr!修改列表和头部,但第二个 set-cdr!只修改头部。如果有人能告诉我这里发生了什么,我将不胜感激,因为再多阅读本章也无法使它更有意义。

都是因为make-queue里面的letmyqcarcdr指的是同一个对象。因此,当您改变 carcdr 时,您正在对同一个对象进行操作。但是 myq 不是。所以改变它不会影响另一个对象。

(define a '(end))
;Value: a

(define b a)
;Value: b

(define c (cons a b))
;Value: c

c
;Value 15: ((end) end)

(set-car! (car c) 'HI)
;Unspecified return value

c
;Value 15: ((hi) hi)

(set-cdr! (cdr c) '(hello))
;Unspecified return value

c
;Value 15: ((hi hello) hi hello)

(set-cdr! c '(end))
;Unspecified return value

c
;Value 15: ((hi hello) end)