2013-07-28 3 views
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을 배우고있다. 그러나 나는 목록에 크기가 "책을 쓰자."라는 항목을 추가 할 때 추가하지 않는 이유를 이해할 수 없다. call은 "Bake Cake"를 반환하고 아이템의 수는 항상 2입니다.요소가 목록에 추가되지 않음

출력은 다음과 같습니다

2 
2 
(Bake cake) 
+3

* cons *은 (는) 해당 인수를 수정하지 않습니다. 대신에 * push *를 사용할 수 있습니다. http://www.lispworks.com/documentation/HyperSpec/Body/m_push.htm –

+0

오, 알겠습니다. 고마워요! 나 또한 defparameter를 다시 시도하고 이제는 작동합니다. 의심 스럽다면 이제는 깨끗한 지 또는 한 번 이상 defparameter하지 않을지 의심됩니다. 나는 그것이 좋지 않은 것처럼 느낀다. 그러나 나는 확실하지 않다. –

+0

* defparameter *를 * defvar *와는 달리 두 번 이상 재사용 할 수 있지만 일반적으로 (setf \ * todo \ * (cons "blabla"\ * todo \ *)와 같은) ("blabla"\ * todo \ *를 누르십시오). –

답변

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

처럼 푸시 생각할 수있는, 그냥이의 일부 구현에 확장 매크로입니다.

+2

표준에 따르면 "장소 항목 푸시 효과는 장소의 하위 양식이 한 번만 평가되고 항목이 장소 이전에 평가된다는 점을 제외하면 (setf place (cons item place))와 같습니다." 자세한 내용은 [here] (http://www.lispworks.com/documentation/HyperSpec/Body/m_push.htm)를 참조하십시오. –

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. 
+0

물론, 그것은 (defin how-many-items (list) if (consp list) (1+ (how-many-items (cdr list))) 0)) –

관련 문제