Common Lisp:为什么这个函数会导致无限递归?

Common Lisp:为什么这个函数会导致无限递归?,lisp,common-lisp,infinite-loop,Lisp,Common Lisp,Infinite Loop,我正在尝试编写一个类似于list的函数(lnn;list not nil),它只附加非nil的值 (list nil 3) --> (NIL 3) (lnn nil 3) --> (3) 这是我到目前为止的代码。出于某种原因,它会在我尝试的任何输入上导致无限递归 (defun lnn (&rest items) (lnn-helper nil items)) (defun lnn-helper (so-far items) (cond ((null items)

我正在尝试编写一个类似于list的函数(lnn;list not nil),它只附加非nil的值

(list nil 3) --> (NIL 3)
(lnn nil 3) --> (3)
这是我到目前为止的代码。出于某种原因,它会在我尝试的任何输入上导致无限递归

(defun lnn (&rest items)
  (lnn-helper nil items))

(defun lnn-helper (so-far items)
   (cond ((null items)
           so-far)
     ((null (car items))
      (lnn-helper so-far (cdr items)))
     (t (lnn-helper (append so-far (list (car items))) (cdr items)))))
有什么想法吗?非常感谢

(defun lnn-helper (so-far &rest items)
  ...)

使用此参数列表,如果始终使用两个参数调用
lnn helper
,则
items
将永远不会为
nil
。删除
&rest
说明符,它就会工作。

Matthias的回答应该会有所帮助。还要注意,这只是一个简单的减少:

(defun lnn (&rest elements)
  (reduce (lambda (elt acc) (if elt (cons elt acc) acc))
          elements
          :from-end t
          :initial-value nil))
甚至(效率更低):

然后:

:)


注:我知道这可能只是一个递归练习,但SCNR。

谢谢你,我做了这个更正,但我仍然得到无限递归。@Miriam它对我有用:
(lnn nil 3)
=>
(3)
<代码>(lnn 1 2 nil 3)=>
(1 2 3)
。什么输入会导致无限递归?我也会尝试将元素CONS到SO-FAR的头部,然后通过返回(NREVERSE-SO-FAR)来结束,这对于短列表来说并不重要,但是APPEND是O(n),所以LNN-HELPER最终是O(n^2)。
(defun lnn (&rest elements)
  (reduce #'cons (remove nil elements) :from-end t :initial-value nil))
(defun lnn (&rest elements)
  (remove nil elements))