setf in a function does not work

后端 未结 1 1294
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-23 19:36

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


        
相关标签:
1条回答
  • 2021-01-23 20:17

    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
    
    0 讨论(0)
提交回复
热议问题