Схема - определить список против символа - PullRequest
4 голосов
/ 31 декабря 2011

Я пытаюсь выяснить кое-что интересное, что происходит в Схеме:

(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, а во втором - нет.Но я не понял, как это работает на самом деле.Схема определения адреса во втором foo, и что делать?Это определяется как список также во втором Foo?или символ?

Спасибо.

1 Ответ

3 голосов
/ 31 декабря 2011

Буквальные списки ('(foo bar baz), в отличие от (list 'foo 'bar 'baz)) не могут быть изменены . Если вы это сделаете, это «ошибка» (т. Е. Поведение не определено).

В этом случае вы наблюдаете, что буквальное значение '(he said:) используется снова и снова, с пониманием, что оно не будет мутировать. Поскольку вы нарушили это понимание, вы получили странное поведение, которое видели.

Напротив, когда вы используете (list 'he 'said:), каждый раз возвращается новый список.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...