我需要实现这样的事情:
(loop for i from 1 to N sum (f i))
除了累积值代表数字列表,如(1 2 3) 并且它们是按元素添加的。换句话说,我想初始化求和 使用(zerov N)并使用(v +)添加后续元素:
(defun v+ (a b) (mapcar '+ a b))
(defun zerov (n) (loop for i from 1 to n collect 0))
是否可以使用循环宏执行此类操作?我可以把它作为一个实现 单独的功能,但我想使用循环或类似循环的宏来表达。 也许有一种方法可以为这种情况定义简单的类似循环的宏?
答案 0 :(得分:3)
(loop with accum = (make-list n :initial-element 0)
for i from 1 to n
do (setq accum (v+ accum (f i)))
finally (return accum))
答案 1 :(得分:2)
LOOP
不可扩展。
我会用正常的LOOP功能编写它:
(let ((result (zerov n)))
(loop for i from 1 to N
do (setf result (v+ result (f i))))
result)
我会把它写成一个函数:
(defun sum (n f init sum)
(let ((result (funcall init n)))
(loop for i from 1 to n
do (setf result (funcall sum result (funcall f i))))
result))
如果你想要这样的功能作为循环宏的直接语言特性,那么另一种选择是ITERATE宏,它比LOOP宏更强大,并且它也是可扩展的。
答案 2 :(得分:0)
(reduce #'v+ (loop for i from 1 to n collect (f i))
:initial-value (zerov n))
请注意,Common Lisp具有适当的“向量”(即,均匀类型的元素序列允许更紧凑的表示和有效的随机访问),所以也许,
(defun v+ (a b) (map-into a #'+ a b))
(defun zerov (n) (make-array n :initial-element 0))
(defun fn (i n) (let ((v (zerov n))) (setf (aref v i) 1) v))
(defun gn (n)
(loop for v = (zerov n) then (v+ v (fn i n)) for i below n
finally (return v)))