1

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?

Wu Li
  • 789
  • 5
  • 6
  • 1
    possible duplicate of [Unexpected persistence of data](http://stackoverflow.com/questions/18790192/unexpected-persistence-of-data) – Joshua Taylor Nov 19 '13 at 15:04
  • 1
    Literal data is _literal data_. If you're familiar with C or Java, you might think of the quoted list in `reset-to-unsorted` as a static variable. When you assign its value to variable and make a change to the underlying object through that variable, you're changing the _one_ value that exists. – Joshua Taylor Nov 19 '13 at 15:09
  • @Joshua Taylor: it's just that the exact effects of changing literal data is undefined in Common Lisp. Thus avoid it. Also I think the general direction of the question is a bit different: what can we do to make sure that a function safely resets a variable? – Rainer Joswig Nov 19 '13 at 15:28
  • 1
    @RainerJoswig Right; using the quoted list isn't in and of itself a bad thing; it just needs to be done knowingly, and the list shouldn't be modified. My comment was aimed at describing what's happening (and not how to fix it). – Joshua Taylor Nov 19 '13 at 15:32
  • Possible duplicate of [Why does this function return a different value every time?](http://stackoverflow.com/questions/8962909/why-does-this-function-return-a-different-value-every-time) – sds Oct 29 '15 at 20:17

1 Answers1

9

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:

  • the data is shared with some other variables, all see the change.
  • an error happens because literal data could be in read-only memory
  • the data is changed

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.

CL-USER 30 > (defparameter *unsorted-lst* nil)
*UNSORTED-LST*

CL-USER 31 > (defun reset-to-unsorted-list ()
               (setf *unsorted-lst*
                     (copy-list '(1 3  0 22 3 1 3 299 31 5 0 3 7 96 24 44)))
               (format t "after reset: ~a~%" *unsorted-lst*))
RESET-TO-UNSORTED-LIST

CL-USER 32 > (setf *unsorted-lst* '(1 2 3))
(1 2 3)

CL-USER 33 > (reset-to-unsorted-list)
after reset: (1 3 0 22 3 1 3 299 31 5 0 3 7 96 24 44)
NIL

CL-USER 34 > (setf (second *unsorted-lst*) 100)
100

CL-USER 35 > (reset-to-unsorted-list)
after reset: (1 3 0 22 3 1 3 299 31 5 0 3 7 96 24 44)
NIL
Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
  • I love you guys, i can always get quick feedback:) Lisp is the language i devoted more time than learning other languages and it always subvert my understanding to computer language. – Wu Li Nov 20 '13 at 00:00