2012-09-21 77 views
1

測試功能如下:爲什麼不能釋放局部變量?

(defun fab (n) 
    (let ((res '(1 1))) 
     (loop for i from 2 to n do 
      (nconc res (list (+ (nth (- i 2) res) (nth (- i 1) res))))) 
     res)) 

$ ECL

... EECL(嵌入式共Lisp的)12.7.1(GIT:未知)

...

>(fab 10) 
(1 1 2 3 5 8 13 21 34 55 89) 
>(fab 20) 
(1 1 2 3 5 8 13 21 34 55 89 2 3 5 8 13 21 34 55 89 144 91 5 8 13 21 34 55 89 144 

然後我重新啓動ECL

>(fab 20) 
(1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946) 

似乎「res」在(fac 10)之後沒有被釋放?

真誠!

回答

4

您應該在let表格中使用(list 1 1)而不是'(1 1)。在Common Lisp中,沒有定義修改文字對象的效果。

(defun fib (n) 
    (let ((res (list 1 1))) ; (list 1 1) instead of '(1 1) 
    (loop for i from 2 to n 
      do (nconc res (list (+ (nth (- i 2) res) (nth (- i 1) res))))) 
    res)) 
1

諸如'(1 1)之類的常量只能由編譯器/解釋器分配一次。您的代碼在此列表上使用NCONC,進行修改,隨後的調用不再看到常量列表'(11),而是修改後的列表。在Common Lisp中,沒有指定在破壞性地修改常量表達式時會發生什麼情況,並且一些實現甚至保護它們免受更改以避免這種意外。如果您需要一個新的常數,請按照人們所說的使用(列表11)或完全避免使用NCONC。

相關問題