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

I'm still learning Lisp but I can't understand why the size of the list doesn't add when I supposedly add the item "Write a book" to it, the cdr call returns "Bake Cake" and the number of items is always two.

The output is:

2
2
(Bake cake)
4

2 回答 2

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

事实上,它是一个宏,在某些实现中可以扩展为这个。

于 2013-07-28T16:36:24.497 回答
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.
于 2013-07-28T17:24:56.637 回答