更新されない定数リストの落とし穴

この前、マスターマインドのプログラムを書いたときに遭遇したこと。
以下の関数 random-digits は、与えられた引数を長さとする数字の順列をひとつ返す。ただしバグあり。

CL-USER> (defun random-digits (num)     ; wrong
           (do ((digits '(0 1 2 3 4 5 6 7 8 9))
                (result nil)
                (count 0 (1+ count))
                (rest 10 (1- rest)))
               ((>= count num) result)
             (let ((d (nth (random rest) digits)))
               (push d result)
               (setq digits (delete d digits)))))
RANDOM-DIGITS
CL-USER> (random-digits 4)
(5 6 4 8)
CL-USER> (random-digits 4)
(NIL 9 NIL NIL)

digits が前の呼び出しで書き換えられたままになっている。使う数字のリストを毎回生成すれば解決する。

CL-USER> (defun random-digits (num)     ; correct
           (do ((digits (list 0 1 2 3 4 5 6 7 8 9))
                (result nil)
                (count 0 (1+ count))
                (rest 10 (1- rest)))
               ((>= count num) result)
             (let ((d (nth (random rest) digits)))
               (push d result)
               (setq digits (delete d digits)))))
RANDOM-DIGITS
CL-USER> (random-digits 4)
(0 7 8 3)
CL-USER> (random-digits 4)
(2 5 9 4)
CL-USER> (random-digits 4)
(0 4 8 6)