Прежде всего, позвольте мне сказать, что я новичок в Лиспе. Честно говоря, я был новичком в течение некоторого времени, но есть еще много вещей, которые я плохо знаю.В чем разница между (list nil) и '(nil) в Lisp?
Пока я писал this question, я придумал странную ошибку в своем коде.
Описание Вот функция, которая вернет список (0 1 ... n)
со списком e
. Он использует rplacd
, чтобы отслеживать последний элемент, чтобы избежать окончательного вызова last
.
Например, (foo 4 '(x))
(0 1 2 3 4 x)
.
«Голова» хранится в a
, что это не просто nil
, потому что есть только один nil
, и никогда его копия (если я правильно понимаю), поэтому я не могу просто добавить к nil
.
(defun foo (n e)
(let* ((a (list nil)) (tail a))
(loop for i to n
do (rplacd tail (setf tail (list i)))
finally (rplacd tail (setf tail e))
(return (cdr a)))))
(defun bar (n e)
(let* ((a '(nil)) (tail a))
(loop for i to n
do (rplacd tail (setf tail (list i)))
finally (rplacd tail (setf tail e))
(return (cdr a)))))
Единственное различие между этими функциями является (list nil)
заменен '(nil)
в bar
. Пока foo
работает как ожидалось, bar
всегда возвращает nil
.
Моя первоначальная догадка заключается в том, что исходный cdr
из a
действительно nil
, а цитируемый список может считаться постоянным. Однако, если я делаю (setf x '(nil)) (rplacd x 1)
, я получаю (nil . 1)
, как и ожидалось, поэтому я должен быть хотя бы частично ошибочным.
Похоже, что скобки «bar» не сбалансированы. – user2357112
@ user2357112 Исправлено. Отсутствующий закрывающий парен был сразу после ''(nil)'. Прошу прощения. –
Я не знаком с Common Lisp, но я верю в схему, все, что цитируется с '' ', должно рассматриваться как неизменяемое. Это держится в Common Lisp? Похоже, вы пытаетесь изменить эту вещь. – user2357112