元素未添加到列表中

时间:2013-07-28 16:26:07

标签: lisp common-lisp

(defparameter *todo* '("Conquer the world" "Bake cake"))

(defun how-many-items (list)
  if (list
      (1+ (how-many-items (cdr list)))
     0))

(defun add-item (item)
  (cons item *todo*)) ; Attempt to add an item to the todo list

(princ (how-many-items *todo*))
(princ '#\newline)
(add-item "Write a book")
(princ (how-many-items *todo*))
(princ '#\newline)
(princ (cdr *todo*))
(princ '#\newline)

我还在学习Lisp,但我无法理解为什么列表的大小没有添加当我想添加项目“写一本书”时,cdr调用返回“Bake Cake”和数字项目总是两个。

输出结果为:

2
2
(Bake cake)

2 个答案:

答案 0 :(得分:4)

您的问题是cons是非破坏性的。这意味着,即使您将项目添加到*todo*包含的列表中,您也不会修改*todo*

> (defparameter x '(1 2 3))
  (1 2 3)
> (cons 1 x)
  (1 1 2 3)
> x
  (1 2 3)

请参阅?没有修改。

而是使用push。它确实修改了它的参数。

> (defparameter x '(1 2 3))
  (1 2 3)
> (push 1 x)
  (1 1 2 3)
> x
  (1 1 2 3)

你可以想到这样的推动

(push x 1) === (setf x (cons 1 x))

事实上,它是一个宏,在某些实现中扩展到了这一点。

答案 1 :(得分:2)

您的输出不可能是真实的,因为您的函数语法错误。

(defun how-many-items (list)
  if (list
      (1+ (how-many-items (cdr list)))
     0))

CL-USER 20 > (how-many-items '(1 2))

Error: The variable IF is unbound.