我是一个带问题的CommonLisp菜鸟。我在下面有这两个功能。
辅助功能:
(defun make-rests (positions rhythm)
"now make those positions negative numbers for rests"
(let ((resultant-rhythm rhythm))
(dolist (i positions resultant-rhythm)
(setf (nth i resultant-rhythm) (* (nth i resultant-rhythm) -1)))))
主要功能:
(defun test-return-rhythms (rhythms)
(let ((positions '((0 1) (0)))
(result nil))
(dolist (x positions (reverse result))
(push (make-rests x rhythms) result))))
当我运行(test-return-rhythms '(1/4 1/8))
时,它会评估为:((1/4 -1/8) (1/4 -1/8))
但是,我希望:(test-return-rhythms '(1/4 1/8))
评估为:((-1/4 -1/8) (-1/4 1/8))
。
我做错了什么?
答案 0 :(得分:1)
make-rests
的实施具有破坏性。
CL-USER> (defparameter *rhythm* '(1/4 1/4 1/4 1/4))
*RHYTHM*
CL-USER> (make-rests '(0 2) *rhythm*)
(-1/4 1/4 -1/4 1/4)
CL-USER> *rhythm*
(-1/4 1/4 -1/4 1/4)
因此,如果您运行测试,第二次迭代将看到(-1/4 -1/8)
,(make-rests '(0) '(-1/4 -1/8))
将返回(1/4 -1/8)
。您在let
中使用make-rests
不会复制列表,只会创建一个引用它的新绑定。在copy-list
中使用let
,或者首先编写非破坏性版本:
(defun make-rests (positions rhythm)
(loop for note in rhythm
for i from 0
collect (if (member i positions) (* note -1) note)))