From: jonathon
Subject: Having trouble deleting first item in list
Date: 
Message-ID: <1119967500.525908.197640@g47g2000cwa.googlegroups.com>
This one has me confused.  I have a list of objects.  Here is the
function to delete one of them:

(defun delete-transaction (index)
  :documentation "Delete a transaction."
  (decf index)
  (with-tm *tm*
    (setf transactions (delete (nth index transactions) transactions)))
;    (delete (nth index transactions) transactions))
  (format t "(tm) Transactions left: ~A~%" (count-transactions)))

'*tm*' is an object that holds transaction objects.
'transactions' is the list of transaction objects internal to *tm*.

This version of the function works as expected.  But when I uncomment
the one line and comment out the setf line, it will never delete the
first (zeroth) entry.  Why is this?

From: jayessay
Subject: Re: Having trouble deleting first item in list
Date: 
Message-ID: <m3zmtav7bo.fsf@rigel.goldenthreadtech.com>
"jonathon" <···········@bigfoot.com> writes:

> This one has me confused.  I have a list of objects.  Here is the
> function to delete one of them:
> 
> (defun delete-transaction (index)
>   :documentation "Delete a transaction."
>   (decf index)
>   (with-tm *tm*
>     (setf transactions (delete (nth index transactions) transactions)))
> ;    (delete (nth index transactions) transactions))
>   (format t "(tm) Transactions left: ~A~%" (count-transactions)))
> 
> '*tm*' is an object that holds transaction objects.
> 'transactions' is the list of transaction objects internal to *tm*.
> 
> This version of the function works as expected.  But when I uncomment
> the one line and comment out the setf line, it will never delete the
> first (zeroth) entry.  Why is this?
> 

DELETE is destructive and:

"delete, when sequence is a list, is permitted to setf any part, car
 or cdr, of the top-level list structure in that sequence. When
 sequence is a vector, delete is permitted to change the dimensions of
 the vector and to slide its elements into new positions without
 permuting them to produce the resulting vector."

http://www.lispworks.com/documentation/HyperSpec/Body/f_rm_rm.htm

You should always set the location holding the sequence being modified.

/Jon

-- 
'j' - a n t h o n y at romeo/charley/november com
From: Kent M Pitman
Subject: Re: Having trouble deleting first item in list
Date: 
Message-ID: <u8y0ulenb.fsf@nhplace.com>
"jonathon" <···········@bigfoot.com> writes:

> This one has me confused.  I have a list of objects.  Here is the
> function to delete one of them:
> 
> (defun delete-transaction (index)
>   :documentation "Delete a transaction."
>   (decf index)
>   (with-tm *tm*
>     (setf transactions (delete (nth index transactions) transactions)))
> ;    (delete (nth index transactions) transactions))
>   (format t "(tm) Transactions left: ~A~%" (count-transactions)))
> 
> '*tm*' is an object that holds transaction objects.
> 'transactions' is the list of transaction objects internal to *tm*.
> 
> This version of the function works as expected.  But when I uncomment
> the one line and comment out the setf line, it will never delete the
> first (zeroth) entry.  Why is this?

You're experiencing the "DELETE bug".

You need to do 
  (setf transactions (delete (nth index transactions) transactions))
DELETE does not receive a pointer to the location that holds the list and
is unable to update it.  You _must_ use the return value from DELETE and
not rely on DELETE for side-effect, since in the case that the element to
be deleted is the first element, DELETE will just _return_ the next tail of
the list that doesn't contain the to-be-deleted elements and will not
have a side-effect--there is no side-effect it could possibly have.
From: Paul F. Dietz
Subject: Re: Having trouble deleting first item in list
Date: 
Message-ID: <e7ydnYsuguLFcVzfRVn-tA@dls.net>
Kent M Pitman wrote:

>  You _must_ use the return value from DELETE and
> not rely on DELETE for side-effect, since in the case that the element to
> be deleted is the first element, DELETE will just _return_ the next tail of
> the list that doesn't contain the to-be-deleted elements and will not
> have a side-effect--there is no side-effect it could possibly have.

Well, not necessarily.  DELETE might have been implemented like this:

(defun delete (item list)
   (cond
    ((null list) nil)
    ((eql (car list) item)
      (cond
       ((null (cdr list)) nil)
       (t
         (setf (car list) (cadr list))
         (setf (cdr list) (cddr list))
         (delete item list)))
    (t (setf (cdr list) (delete item (cdr list)))
       list)))

The bug is unavoidable if there is nothing in the list except
the item to be deleted.

	Paul
From: Kent M Pitman
Subject: Re: Having trouble deleting first item in list
Date: 
Message-ID: <ur7elzx5l.fsf@nhplace.com>
"Paul F. Dietz" <·····@dls.net> writes:

> Kent M Pitman wrote:
> 
> >  You _must_ use the return value from DELETE and
> > not rely on DELETE for side-effect, since in the case that the element to
> > be deleted is the first element, DELETE will just _return_ the next tail of
> > the list that doesn't contain the to-be-deleted elements and will not
> > have a side-effect--there is no side-effect it could possibly have.
> 
> Well, not necessarily.  DELETE might have been implemented like this:
> 
> (defun delete (item list)
>    (cond
>     ((null list) nil)
>     ((eql (car list) item)
>       (cond
>        ((null (cdr list)) nil)
>        (t
>          (setf (car list) (cadr list))
>          (setf (cdr list) (cddr list))
>          (delete item list)))
>     (t (setf (cdr list) (delete item (cdr list)))
>        list)))

Yes, I've long known this.  But
 (a) this is makes predictable structure sharing unpredictable
 (b) doesn't fix this bug:

> The bug is unavoidable if there is nothing in the list except
> the item to be deleted.

Given this, the above is an exercise in futility.
You still need the SETQ.
From: Matthias Buelow
Subject: Re: Having trouble deleting first item in list
Date: 
Message-ID: <86psu6o75s.fsf@drjekyll.mkbuelow.net>
"jonathon" <···········@bigfoot.com> writes:

>This version of the function works as expected.  But when I uncomment
>the one line and comment out the setf line, it will never delete the
>first (zeroth) entry.  Why is this?

Because it cannot destructively remove the first element of a list.
You'd have to adjust the references in all variables pointing to that
list instead to do so.
If you visualize it on paper with the list in box-notation, you'll see
why this is so.

mkb.
From: justinhj
Subject: Re: Having trouble deleting first item in list
Date: 
Message-ID: <1119979247.649876.227450@g47g2000cwa.googlegroups.com>
If you're always deleting the first item in the list you could just do
:

(defun delete-first( lst )
  (cdr lst))

(setf lst '( a b c 1 2 3 ))

(setf lst (delete-first lst))
From: jonathon
Subject: Re: Having trouble deleting first item in list
Date: 
Message-ID: <1120008879.426537.60920@g47g2000cwa.googlegroups.com>
Thank you all for your answers.  You were right on the money and
pointed out the correct fix.  Thanks again!