i defined a special variable *unsorted-lst* and a function for reseting this variable in my script:
(defparameter *unsorted-lst* nil)
(defun reset-to-unsorted-list ()
(setf *unsorted-lst* '(1 3 0 22 3 1 3 299 31 5 0 3 7 96 24 44))
(format t "after reset: ~a~%" *unsorted-lst*)
)
After that i copy them to SBCL console for testing, i did:
* (setf *unsorted-lst* '(1 2 3))
(1 2 3)
* (reset-to-unsorted-list)
after reset: (1 3 0 22 3 1 3 299 31 5 0 3 7 96 24 44)
NIL
Everything works fine so far. Then i did
* (setf (second *unsorted-lst*) 100)
100
* (reset-to-unsorted-list)
after reset: (1 100 0 22 3 1 3 299 31 5 0 3 7 96 24 44)
NIL
The setf in function seems did not work, the second element value still was 100. It really confuse me. I had to type setf command directly in console to make the change:
* (setf *unsorted-lst* '(1 3 0 22 3 1 3 299 31 5 0 3 7 96 24 44))
(1 3 0 22 3 1 3 299 31 5 0 3 7 96 24 44)
* *unsorted-lst*
(1 3 0 22 3 1 3 299 31 5 0 3 7 96 24 44)
Now it works. I cannot tell what wrong it is? Are there some misunderstanding of setf? or variable?
You need to set the variable data to a new fresh list, which is a copy of the literal data. Don't let the global variable point to local literal data of a function.
What you are looking at is also undefined behavior in a Common Lisp program.
You use literal data in the function. Later you modify this literal data by changing the second element of the list. What exactly happens is undeclared. Some possible outcomes:
Many implementation just change the literal data. Here in this case the data of the function is changed.
If you want the function to reset the variable value and create not-literal data, you need to copy the literal list first.