2012-03-17 10 views
0

私は各関数のローカル変数のみを使用していますが、複数回実行した後の結果は変数に残っているように見えますが、 &新しい結果。なにが問題ですか?ローカル変数は以前の実行からデータを保持します

(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

答えて

3

頻繁に聞かれる質問です。この質問のコピーが必要です(ic!)stackoverflowに。

funcAにはリテラルデータが含まれています。このデータは毎回funcBに渡され、そこで変更されます。

実行ごとに新しいデータを作成する必要があります。 COPY-TREEを使用してください。

また、リテラルデータを変更すると、Common Lisp標準に従って定義されていない結果が生じる可能性があることにも注意してください。たとえば、すべてのリテラルデータを読み取り専用のデータメモリセグメントに入れたり、同様のリテラルデータをいくつかの場所で再利用してスペースを節約するコンパイラを想像するコンパイラを想像してみてください。

+1

''(())の代わりに、'(list(list)) 'のようなこともできますか? – lindes

+1

@lindes:はい。新しくconsedされたデータは何でもします。 –

関連する問題