我有一个函数,它接受一个列表并替换一些元素。我已将其构造为闭包,以便无法在函数外修改自由变量。
(defun transform (elems)
(lexical-let ( (elems elems) )
(lambda (seq)
(let (e)
(while (setq e (car elems))
(setf (nth e seq) e)
(setq elems (cdr elems)))
seq))))
我在列表列表中将其称为。</ p>
(defun tester (seq-list)
(let ( (elems '(1 3 5)) )
(mapcar (transform elems) seq-list)))
(tester (list (reverse (number-sequence 1 10))
'("a" "b" "c" "d" "e" "f")))
=> ((10 1 8 3 6 5 4 3 2 1) ("a" "b" "c" "d" "e" "f"))
似乎没有将该函数应用于提供给tester()的列表的第二个元素。但是,如果我明确地将此函数应用于单个元素,它就可以...
(defun tester (seq-list)
(let ( (elems '(1 3 5)) )
(list (funcall (transform elems) (car seq-list))
(funcall (transform elems) (cadr seq-list)))))
(tester (list (reverse (number-sequence 1 10))
'("a" "b" "c" "d" "e" "f")))
=> ((10 1 8 3 6 5 4 3 2 1) ("a" 1 "c" 3 "e" 5))
如果我使用与上面相同的概念编写一个简单的函数,mapcar似乎工作......我可能做错了什么?
(defun transform (x)
(lexical-let ( (x x) )
(lambda (y)
(+ x y))))
(defun tester (seq)
(let ( (x 1) )
(mapcar (transform x) seq)))
(tester (list 1 3))
=> (2 4)
由于
答案 0 :(得分:2)
在第一次调用闭包后,关闭变量elems
设置为nil;因此所有后续调用只能看到nil。您的第二个示例有效,因为transform
的每个实例都会生成一个新的闭包。
这应该有效:
(defun transform (elems)
(lexical-let ((elems elems))
(lambda (seq)
(dolist (e elems seq)
(setf (nth e seq) e)))))