Scheme - 定义列表与符号

时间:2011-12-31 10:54:36

标签: scheme

我试图弄清楚在Scheme中发生的事情:

(define last-pair
     (lambda (x)
       (if (null? (cdr x))
           x
           (last-pair (cdr x)))))

当我以这种方式定义foo时:

(define foo
  (lambda ()
    (let ((s (list 'he 'said:)))
      (set-cdr! (last-pair s)
                (list 'ha 'ha))
      s)))

并且运行foo 3次,我得到了:

(he said: ha ha)
(he said: ha ha)
(he said: ha ha)

但是当我以这种方式定义foo时:

(define foo
  (lambda ()
    (let ((s '(he said:))) 
      (set-cdr! (last-pair s)
                (list 'ha 'ha))
      s)))

并且运行foo 3次,我得到了:

(he said: ha ha)
(he said: ha ha ha ha)
(he said: ha ha ha ha ha ha)

但为什么呢?我的第一个想法是,我们在第一个foo中建立了新的列表,而在第二个我们没有。但我不明白它是如何运作的。 Scheme在第二个foo中定义地址,并做什么?它是否也在第二个foo中定义为列表?还是一个符号?

感谢。

1 个答案:

答案 0 :(得分:3)

文字列表('(foo bar baz),而不是(list 'foo 'bar 'baz))是not allowed to be mutated。如果你这样做,“这是一个错误”(即行为未定义)。

在这种情况下,您所观察到的是文字'(he said:)被反复使用,并且理解它不会变异。由于你违反了这种理解,你会得到你所看到的奇怪行为。

相反,当您使用(list 'he 'said:)时,每次都会返回一个新列表。