LISP function affecting other function [duplicate]

≡放荡痞女 提交于 2019-12-25 08:23:11

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!