'(0 0 0)
в коде - это буквальные данные.Изменение этих данных имеет неопределенное поведение.Обычные реализации Lisp могут не обнаружить его во время выполнения (если, например, данные не помещены в некоторое пространство памяти только для чтения).Но это может иметь нежелательные последствия.
вы видите, что эти данные могут быть (и часто используются) для различных вызовов одной и той же функции
Одна из наиболее тонких возможных ошибок заключается в следующем: Common Lisp был определен с различными оптимизациями, которые могут быть выполнены с помощью компилятора.Например, компилятору разрешено повторно использовать данные:
Пример:
(let ((a '(1 2 3))
(b '(1 2 3)))
(list a b))
В приведенном выше фрагменте кода компилятор может обнаружить, что литеральные данные a
иb
- это EQUAL
.Тогда обе переменные могут указывать на одни и те же литеральные данные.Модификация может работать, но изменения видны с a
и b
.
Сводка: Модификация литеральных данных является источником нескольких тонких ошибок.Избегайте этого, если это возможно.Тогда вам нужно cons новых объектов данных. В общем случае означает выделение новых, новых структур данных во время выполнения.