10 lisp loops common-lisp
假设我运行以下内容
(loop for i to 4 collect i)
Run Code Online (Sandbox Code Playgroud)
然后我得到一个清单(0 1 2 3 4)
.现在,如果我想在结果中添加一些内容,我可以使用rplacd
它的last
元素,但由于Lisp列表是链表,因此效率不高.这里的清单非常小,但这只是一个例子.
但是,由于循环工具以递增的顺序返回列表,因此它必须跟踪指向最后一个元素的指针,并使用rplacd
或等效的更新结果.A macroexpand-all
显示它是CCL的作用,也可能是其他lisps.
问题:有没有办法在finally
条款中使用这个"指针" ?它允许一个人在结果上附加一些东西,这有时是有用的.
当然,编码指针机制很容易,但它并不是那么好.例如,以下内容将列表附加e
到列表中(0 1 ... n)
.
(defun foo (n e)
(let* ((a (list nil)) (tail a))
(loop for i to n
do (rplacd tail (setf tail (list i)))
finally (rplacd tail (setf tail e))
(return (cdr a)))))
Run Code Online (Sandbox Code Playgroud)
每次迭代和一次额外迭代的额外比较为您提供:
CL-USER 2 > (defun foo (n e &aux (z (1+ n)))
(loop for i to z
unless (= i z)
collect i
else
nconc e))
FOO
CL-USER 3 > (foo 4 '(f o o))
(0 1 2 3 4 F O O)
Run Code Online (Sandbox Code Playgroud)