我有以下Common Lisp代码,并且对counter
变量的绑定方式感到困惑。
(defun count-bases (strand)
(let ((counter (list '(a . 0) '(c . 0) '(g . 0) '(t . 0))))
(inspect counter)
(labels ((inc-counter (base)
(incf (cdr (assoc base counter)))))
(dolist (element strand (mapcar #'(lambda (pair) (list (car pair) (cdr pair))) counter))
(cond ((symbolp element) (inc-counter element))
(t (inc-counter (first element))
(inc-counter (second element))))))))
我希望每次调用此函数时,值'((a . 0) (c . 0) (g . 0) (t . 0))
都绑定到counter
变量,并且在函数完成时counter
变量会超出范围。但是,第二次调用函数(如下所示)时,counter
变量保留了第一次调用时的值。
CL-USER> (count-bases '(a t t a g c a c))
The object is a proper list of length 4.
0. 0: (A . 0)
1. 1: (C . 0)
2. 2: (G . 0)
3. 3: (T . 0)
> E
((A 3) (C 2) (G 1) (T 2))
CL-USER> (count-bases '(a t t a g c a c))
The object is a proper list of length 4.
0. 0: (A . 3)
1. 1: (C . 2)
2. 2: (G . 1)
3. 3: (T . 2)
> E
((A 6) (C 4) (G 2) (T 4))
CL-USER>
有人能解释一下每次调用函数时在这里发生了什么以及如何绑定绑定变量吗?非常感谢。
答案 0 :(得分:4)
这是一个常见问题。
您正在修改源代码中的文字常量数据。 LIST调用中的con单元格都是文字常量。您已经引用了它们。
使用lamdba x,y: Value.Success(y+1, x) if x[y] == "<" else Value.failure(y, x)
创建一个新列表。
copy-tree
或者调用(let ((counter (copy-tree '((a . 0) (c . 0) (g . 0) (t . 0)))))
...)
而不是引用cons单元格。