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

时间:2011-10-29 13:16:07

标签: 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)
           so-far)
     ((null (car items))
      (lnn-helper so-far (cdr items)))
     (t (lnn-helper (append so-far (list (car items))) (cdr items)))))

有什么想法吗?非常感谢。

2 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:2)

马蒂亚斯的回答应该有所帮助。另请注意,这只是一个简单的缩减:

(defun lnn (&rest elements)
  (reduce (lambda (elt acc) (if elt (cons elt acc) acc))
          elements
          :from-end t
          :initial-value nil))

甚至(效率较低):

(defun lnn (&rest elements)
  (reduce #'cons (remove nil elements) :from-end t :initial-value nil))

然后:

(defun lnn (&rest elements)
  (remove nil elements))

:)

P.S。:我知道这可能只是一次递归练习,但SCNR。