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)

私はまだLispを学んでいますが、リストに「本を書く」という項目を追加すると思われるリストのサイズが追加されない理由を理解できません.cdr呼び出しは「Bake Cake」を返し、項目の数はいつも二人。

出力は次のとおりです。

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 に答える