У меня странное поведение при вызове деструктивного определения, получающего в качестве аргумента локальную переменную типа список, созданный с цитатой.
Деструктивная функция:
(defun insert-at-pos (pos list elem)
(if (= pos 0)
(cons elem list)
(let ((aux-list (nthcdr (1- pos) list)))
(setf (rest aux-list) (cons elem (rest aux-list)))
list)))
НЕПРАВИЛЬНО: локальная переменная - это список, созданный с помощью специального оператора quote.
(defun test ()
(let ((l '(1 2 3)))
(print l)
(insert-at-pos 2 l 4)
(print l)))
> (test)
(1 2 3)
(1 2 4 3)
(1 2 4 3)
> (test)
(1 2 4 3)
(1 2 4 4 3)
(1 2 4 4 3)
> (test)
(1 2 4 4 3)
(1 2 4 4 4 3)
(1 2 4 4 4 3)
ПРАВИЛЬНО: локальная переменная - это список, созданный с помощью функции list < / а>.
(defun test2 ()
(let ((l (list 1 2 3)))
(print l)
(insert-at-pos 2 l 4)
(print l)))
or
(defun test2 ()
(let ((l '(1 2 3)))
(print l)
(setf l (cons (first l) (cons (second l) (cons 4 (nthcdr 2 l)))))
(print l)))
> (test2)
(1 2 3)
(1 2 4 3)
(1 2 4 3)
> (test2)
(1 2 3)
(1 2 4 3)
(1 2 4 3)
> (test2)
(1 2 3)
(1 2 4 3)
(1 2 4 3)
Кто-нибудь знает причину такого странного поведения?
test2
выsetf
переменнуюl
, что совершенно нормально. В вашем первоначальномinsert-at-pos
определении выsetf
место, часть структуры cons-узла, которая является запрещенной.(setf (rest aux-list) ...
переводится вRPLACD
звонок. - person Will Ness   schedule 03.06.2013