Локальная переменная хранит данные из предыдущего выполнения

В приведенном ниже коде, хотя (я полагаю) я использую только локальные переменные в каждой функции, результат после многократного выполнения выглядит так, как будто данные остаются в переменных, и в итоге получается добавление старого и нового результата. Что случилось?

(defun funcC (target res)
  (cond
   ((null res) (list (list target 1)))
   ((equal (car (car res)) target)
    (setf (cadr (car res)) (+ (cadr (car res)) 1))
    res)
   (t (setf (cdr res) (funcC target (cdr res))) res)
  ))
(defun funcB (l res)
  (cond ((null l) nil)
    ((atom l) (funcC l res))
    ((atom (car l)) 
     (funcB (car l) res)
     (funcB (cdr l) res))
    ((listp (car l)) (funcB (car l) res))
    (t (funcB (cdr l) res)))
  res
)
(defun funcA (l)
  (cdr (funcB l '(())))
)

Результат:

Break 27 [30]> lb
(10 7 7 7 4 3 7 3 10 10)
Break 27 [30]> (funcA lb)
((10 3) (7 4) (4 1) (3 2))   ; I want this result to repeat in the next run but...
Break 27 [30]> (funcA lb)
((10 6) (7 8) (4 2) (3 4))   
Break 27 [30]> (funcA lb)
((10 9) (7 12) (4 3) (3 6))  ; Each run adds up to results from previous run

Окружающая среда: Ubuntu 11.10, GNU CLISP 2,49

1 ответ

Это часто задаваемый вопрос. Должны быть копии (sic!) Этого вопроса на stackru.

Ваш funcA содержит буквальные данные. Эти данные передаются каждый раз funcB и там модифицирован.

Вы должны сделать новую копию этих данных для каждого запуска. использование COPY-TREE,

Также обратите внимание, что изменение литеральных данных может иметь неопределенные последствия в соответствии со стандартом Common Lisp. Например, представьте компилятор, который помещает все литеральные данные в сегменты памяти только для чтения, или представьте компилятор, который повторно использует аналогичные литеральные данные в нескольких местах для экономии места.

Другие вопросы по тегам