I’ve written the following bit of code to simulate rolling a six-sided die a number of times and counting how many times each side landed up:
(defun dice (num)
(let ((myList '(0 0 0 0 0 0)))
(progn (format t "~a" myList)
(loop for i from 1 to num do
(let ((myRand (random 6)))
(setf (nth myRand myList) (+ 1 (nth myRand myList)))))
(format t "~a" myList))))
The function works great the first time I call it, but on subsequent calls the variable myList starts out at the value it had at the end of the last call, instead of being initialized back to all zeros like I thought should happen with the let statement. Why does this happen?
This is a result of using a constant list in the initializer:
Change that line to:
and it will behave as you expect. The first line only results in an allocation once (since it’s a constant list), but by calling
listyou force the allocation to occur every time the function is entered.edit:
This may be helpful, especially towards the end. Successful Lisp
The answer to this question may also be helpful.
This uses the
loopkeywordcollectingwhich collects the results of each iteration into a list and returns the list as the value of theloop.