1

I have a Node class that has an 'element' slot which contains a list with numbers and one letter, for example:

'(1 2 3 b 4 5 6)


(defclass node ()
  ((element :reader get-element
            :writer set-element
            :initform '()
            :initarg :element
            :documentation "The element"))

Part of the program is supposed to take the 'element' slot, swap the letter with one of the numbers and finally create a new Node object with the swapped list as its 'element' slot. I already have a swap function that receives a list and two members of that list and using the rotatef function it swaps them.

To test that the swap function was working I created the following piece of code which stores in a temporary variable the element and swaps the letter 'b' with a number in the list:


(setf root (make-instance 'node))
(set-element '(1 2 3 b 4 5 6 7 8) root)

(setf temp (get-element root)) (swap temp 'b 4)

The problem is that the 'element' slot of the root object is swapped along with temp. Strangely I tried changing the swap function to reverse and it doesn't modify any of the two.

I don't know if there's any way to assign a slot to a variable or a way to prevent the above from happening.

Thanks.

Svante
  • 50,694
  • 11
  • 78
  • 122
Xap
  • 77
  • 3
  • 7

2 Answers2

3

Some other remarks:

  • instead of a getter and setter method, use an accessor method. That's usually preferred.

  • lists are created with functions like LIST or COPY-LIST. A list written as '(1 b 2) is in source code a literal constant and should not be changed. It is undefined in the CL standard what happens if you try to change a literal list. This can have unwanted effects. If you have a literal list and you want to modify it, you should first copy it with COPY-LIST (or COPY-TREE) and modify that copy.

  • you also need to learn the difference between non-destructive operations like REVERSE and possibly destructive operations like NREVERSE. If you want the original list to be unchanged, use non-destructive operations. The nature of the list or sequence operations is described in the Common Lisp Hyperspec for each operation.

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
2

Reverse creates and returns a new list. Rotatef (just as setf, incf and the like) modify a place. You will have to copy-list or copy-tree your element to create a new list that you then modify.

Svante
  • 50,694
  • 11
  • 78
  • 122
  • Thanks a lot! I have never heard of those list functions. I was previously trying to "copy" the list using append, initializing temp as an empty list and appending get-element but it didn't work, temp remained empty. – Xap Sep 25 '10 at 23:20