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

发布于 2024-12-12 10:24:29 字数 496 浏览 1 评论 0原文

我正在尝试编写一个类似于 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)))))

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

I am trying to write a function (lnn; list-not-nil) similar to list that only appends values that are not nil.

(list nil 3) --> (NIL 3)
(lnn nil 3) --> (3)

Here is the code I have so far. For some reason it causes infinite recursion on any input that I try.

(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)))))

Any ideas? Thanks very much.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

花间憩 2024-12-19 10:24:29
(defun lnn-helper (so-far &rest items)
  ...)

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

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

With this argument list, items will never be nil if you always call lnn-helper with two arguments. Remove the &rest specifier, and it'll work.

青芜 2024-12-19 10:24:29

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

(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))

:)

PS:我知道这可能只是递归的练习,但是 SCNR。

Matthias' answer should have helped. Also note, that this is just a simple reduction:

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

Or even (less efficient):

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

Then:

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

:)

P.S.: I know this was probably just an exercise in recursion, but SCNR.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文