问题
ith the code below, even though (I believe) I'm only using local variables in each function, the result after running multiple times looks like data remain in variables and it ends up adding old & new result. What is wrong?
(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 '(())))
)
Result:
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
Environment: Ubuntu 11.10, GNU CLISP
2.49
回答1:
That's a frequently asked question. There should be copies (sic!) of this question on stackoverflow.
Your funcA
contains literal data. This data is passed every time to funcB
and modified there.
You should make a fresh copy of that data for each run. Use COPY-TREE
.
Note also that modifying literal data might have undefined consequences according to the Common Lisp standard. Imagine for example a compiler which puts all literal data in read-only data memory segments or imagine a compiler which reuses similar literal data in several places to save space.
来源:https://stackoverflow.com/questions/9748311/local-variable-keeps-data-from-previous-execution