Question

The test function is as below:

(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 (Embeddable Common-Lisp) 12.7.1 (git:UNKNOWN)

...

>(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

Then i restart ECL

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

It seems the "res" is not freed after the (fac 10) ?

Sincerely!

Was it helpful?

Solution

You should use (list 1 1) rather than '(1 1) in the let form. In Common Lisp, the effects of modifying literal objects are not defined.

(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))

OTHER TIPS

Constants such as '(1 1) are only allocated once by the compiler / interpreter. Your code uses NCONC on this list, modifying, and subsequent calls do no longer see the constant list '(1 1) but the modified one. In Common Lisp it is unspecified what happens when on destructively modifies constant expressions, and some implementations even protect them against changes to avoid such surprises. If you need a fresh new constant, do as people said and use (list 1 1) or avoid using NCONC altogether.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top