问题
I noticed that when I call the function fillBoard, it seems to work as it fills the list passed to it as I want, but it has a very weird side effect. Somehow once fillBoard is called, the clearBoard function will only return the list returned by fillBoard. Additionally if I call fillBoard again it will continue to update the value returned in clearBoard.
As far as I understand, there should be a new instance of the list variable in clear everytime its called, so I don't see how its being modified or how its storing a new value.
I am passing fillBoard an empty list like ((0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0)), and it will return a list like ((1 2 3 0) (0 6 0 0) (0 0 0 0) (0 0 0 0)), which is then what clearBoard returns.
(defun fillBoard (list)
(let ((numVals (+ 4 (random 3)))
(rand 0)
(val1 0)
(val2 0))
(dotimes (x numVals)
(setf val1 (random 3))
(setf val2 (random 3))
(setf rand (nth val1 (nth val2 soln)))
(prin1 rand)
(write-line " ")
(if (= (nth val1 (nth val2 list)) 0)
(setf (nth val1 (nth val2 list)) rand)))
list))
(defun clearboard ()
(let (( list '((0 0 0 0) (0 0 0 0) (0 0 0 0) (0 0 0 0))))
list))
EDIT: I did seem to alleviate the issue by having clearBoard be passed a list then setting it directly to the blank board as opposed to a local variable, then returning that instead. However, I am still curious as to how what was happening in the original issue
回答1:
EQness of your return result
Your function returns the same literal list all the time. It is data embedded into your code. Don't modify it.
CL-USER 4 > (eq (clearboard) (clearboard))
T
EQ
returns T
, because the first cons in both lists is actually the same cons.
Allocate fresh new lists
Use COPY-TREE
inside clearboard
to create a newly allocated list of lists, instead of returning the same literal list over and over:
(defun clearboard ()
(copy-tree '((0 0 0 0)
(0 0 0 0)
(0 0 0 0)
(0 0 0 0))))
CL-USER 5 > (eq (clearboard) (clearboard))
NIL
Don't modify literal data
Literal data here is a data list, which is embedded in your code. Don't modify your code.
回答2:
The list returned by clearboard is defined as a constant structure. When you modify it in fillBoard, you are not modifying a copy, but the structure itself. Generate the board instead with
(loop repeat 4 collect (make-list 4 :initial-element 0))
来源:https://stackoverflow.com/questions/40335429/lisp-function-affecting-other-function