ZXJ
ZXJ

Reputation: 3

Why setq cuts my list

As the title says, I'm trying to append items to a list called solution, below is the code:

(defun add-solution (n)
    (let ((solution)) 
        (do((current-node '() (next-state current-node n nil)))
            ((equal current-node '(0 0 0 0)) solution)
            (if (goal-test current-node n)
                (progn
                    (format t "Cur: ~S~%" current-node)
                    (setq solution (append solution (list current-node)))
                    (format t "Solution: ~S~%" solution)
                )
            )   
        )
    )
)

Each time the new current-node is a something like:(1 7 8 14), (2 4 11 13), but when the loop returns it returns ((1) (2)).. What I need is (((1 7 8 14) (2 4 11 13)). Not sure what happened there??

edit: I added the format functions just before and after the setq, and the output was like:


Cur: (1 7 8 14)
Solution: ((1 7 8 14))
Cur: (2 4 11 13)
Solution: ((1)(2 4 11 13))

and after the whole thing is done the returned value became ((1) (2)) again. I'm not really doing anything that modifies solution...

Upvotes: 0

Views: 74

Answers (1)

Rainer Joswig
Rainer Joswig

Reputation: 139251

Looks like your error is somewhere else.

Style:

I would write/format the code like this:

(defun add-solution (n)
  (do ((solution nil)
       (current-node '() (next-state current-node n nil)))
      ((equal current-node '(0 0 0 0)) solution)
    (when (goal-test current-node n)
      (setq solution (append solution (list current-node))))))

Note that this is bad code, since you are APPENDING an item to the end of a list in a loop. This is a potentially very costly operation. Lisp lists are optimized for adding to the front, not to the end.

Upvotes: 2

Related Questions