[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: >Writing Destructive Fun



        Reply to:   RE>>Writing Destructive Func
First of all, it's perfectly possible to write a function which modifies a
list destructively 
in the way you specify, except that it won't work if passed an empty list.

? (defun add-to-front (theList new-element)
  (if (null theList)
    (error "can't destructively modify NIL")
    (let ((new-cons (cons (car theList) (cdr theList))))
      (setf (car theList) new-element)
      (setf (cdr theList) new-cons)
      theList)))
ADD-TO-FRONT
? (setf test-list '(a b c))
(A B C)
? (add-to-front test-list 'k)
(K A B C)
? test-list
(K A B C)

If the list in question is bound to a global symbol, an alternate approach
is the following.

? (defun add-to-front2 (theListname new-element)
    (push new-element (symbol-value theListname)))
ADD-TO-FRONT2
? (add-to-front2 'test-list 'J)
(J K A B C)
? test-list
(J K A B C)

Finally, a more general solution than either of the previous ones is to
effectively pass in a 
pointer to the list by adding an extra cons cell to the beginning of the
list, then always 
take the cdr of the list when you want to access the list.

? (defun add-to-front3 (ListWithHeader new-element)
(push new-element (cdr ListWithHeader)))
ADD-TO-FRONT3
? (setf list-with-header (list '***list-header***))
(***LIST-HEADER***)
? (add-to-front3 list-with-header 'a)
(A)
? list-with-header
(***LIST-HEADER*** A)
? (add-to-front3 list-with-header 'b)
(B A)
? list-with-header
(***LIST-HEADER*** B A)