From: Greg Schohn
Subject: delete?
Date: 
Message-ID: <EnAyEK.Epx@fyi.net>
could anybody explain to me why this code has problems deleting the first
element of a list when it is selected (it will remove everything else - as 
I would expect it too)...

also - what is a good current (near ANSI) common LISP interpreter?  (I'm 
currently using CMUCL - but it is getting VERY old...

thanks,
Greg
(new to LISP)

From: Raymond Toy
Subject: Re: delete?
Date: 
Message-ID: <4nen1x7j8g.fsf@rtp.ericsson.se>
···@jules.res.cmu.edu (Greg Schohn) writes:

> 
> also - what is a good current (near ANSI) common LISP interpreter?  (I'm 
> currently using CMUCL - but it is getting VERY old...
> 
Of the "free" versions, CMUCL is probably closer to ANSI CL than any
other.  Franz Allegro Common Lisp, which is available for Linux, is
probably ANSI CL.

In what way is CMUCL "getting VERY old"?

Ray
From: Erik Naggum
Subject: Re: delete?
Date: 
Message-ID: <3094662584086617@naggum.no>
* Greg Schohn
| could anybody explain to me why this code has problems deleting the first
| element of a list when it is selected ...

  DELETE is like NREVERSE or SORT in that they all work through destructive
  operations on (parts of) the argument value, but it is the value returned
  from the function that has all the properties of the performed operation.
  any prior access paths to the argument value will now hold a value that
  is not useful unless you know _exactly_ what the function did.  it's safe
  to assume that you don't, since you had to ask.  in many cases, it is not
  even possible to know exactly what a function did since an implementation
  is free to perform the function in any way that maintains the specified
  invariants and results.  e.g., DELETE on a list is likely to return the
  first cons cell whose car is _not_ the item you want deleted.  if you
  think about it, you realize that it couldn't do anything else, because it
  would have needed access to whatever contained the list as its value to
  do that and only the caller has access to that since Lisp calls functions
  with the computed _values_ of all arguments.  you will therefore have to
  assign the returned value back to the variable to get the desired effect
  of deleting the first element.  (isn't this in some FAQ already?)

#:Erik
-- 
The year "98" was new 1900 years ago.  |  Help fight MULE in GNU Emacs 20!
Be year 2000 compliant, write "1998"!  |  http://sourcery.naggum.no/emacs/
From: Ruddy &
Subject: Re: delete?
Date: 
Message-ID: <EnB25q.34F@fyi.net>
BTW - sorry that I forgot to include the code (using a new newsreader)...
here it is

(defun next_rnd (l)
  (let* ((index (floor(random(length l))))
         (val (elt l index)))
    (progn (delete val l) (print l) val)))


In article <··········@fyi.net>,
	···@jules.res.cmu.edu (Greg Schohn) writes:
> could anybody explain to me why this code has problems deleting the first
> element of a list when it is selected (it will remove everything else - as 
> I would expect it too)...
> 
> also - what is a good current (near ANSI) common LISP interpreter?  (I'm 
> currently using CMUCL - but it is getting VERY old...
> 
> thanks,
> Greg
> (new to LISP)

-- 

                                             Something (c) George Harrison
---------------------------------------|       Abbey Road | Beatles, 1969
Something in the way that she moves.   |-------------------------------------
Attracts me like no other lover.       |  You're asking me will my love grow
Something in the way that she woos me, |  I don't know, I don't know
I don't want to leave her now,         |  You stick around now it may show
You know I believe and how.            |  I don't know, I don't know
From: dan corkill
Subject: Re: delete?
Date: 
Message-ID: <34ca6fc9.0@rcfnews.cs.umass.edu>
>> could anybody explain to me why this code has problems deleting the first
>> element of a list when it is selected (it will remove everything else - as 
>> I would expect it too)...


Don't confuse Common Lisp functions that change structure with
functions that work by "effect".  There are many of these, with delete and
sort among the most frequent "gotcha"'s for new programmers.

Be sure you do (setf list (delete item list)), not simply (delete item list)
and you will find all is well...  (Think of delete as remove that CAN change
its list argument.  In the case of deleting the first element, it doesn't
change list at all!)

-- Dan Corkill
   Blackboard Technology
From: Hartmann Schaffer
Subject: Re: delete?
Date: 
Message-ID: <34CAC402.1C7609A@netcom.ca>
Ruddy & wrote:
> 
> BTW - sorry that I forgot to include the code (using a new newsreader)...
> here it is
> 
> (defun next_rnd (l)
>   (let* ((index (floor(random(length l))))
>          (val (elt l index)))
>     (progn (delete val l) (print l) val)))

Delete returns a list with the object deletet.  It doesn't change the
argument list.

Btw, according to my newsreader you posted as root.  Makes it hard to
reply by email (sometimes)


> > could anybody explain to me why this code has problems deleting the first
> > element of a list when it is selected (it will remove everything else - as
> > I would expect it too)...

> 
>                                              Something (c) George Harrison
> ---------------------------------------|       Abbey Road | Beatles, 1969
> Something in the way that she moves.   |-------------------------------------
> Attracts me like no other lover.       |  You're asking me will my love grow
> Something in the way that she woos me, |  I don't know, I don't know
> I don't want to leave her now,         |  You stick around now it may show
> You know I believe and how.            |  I don't know, I don't know

-- 

-------------------------------------------------------------------------

Hartmann Schaffer
Guelph, Ontario, Canada
········@netcom.ca (hs)
From: Erik Naggum
Subject: Re: delete?
Date: 
Message-ID: <3094694471896591@naggum.no>
* Hartmann Schaffer
| Delete returns a list with the object deletet.  It doesn't change the
| argument list.

  please, don't post half-correct answers.  it is REMOVE that does not
  change the argument value�, while DELETE must be expected to do so.

� REMOVE and DELETE work on sequences.  e.g., (delete #\e "makeunbound")

#:Erik
-- 
The year "98" was new 1900 years ago.  |  Help fight MULE in GNU Emacs 20!
Be year 2000 compliant, write "1998"!  |  http://sourcery.naggum.no/emacs/
From: Ken Tilton
Subject: Re: delete?
Date: 
Message-ID: <34CE0C4E.14DD496E@liii.com>
Ruddy & wrote:

> BTW - sorry that I forgot to include the code (using a new newsreader)...
> here it is
>
> (defun next_rnd (l)
>   (let* ((index (floor(random(length l))))
>          (val (elt l index)))
>     (progn (delete val l) (print l) val)))
>
> In article <··········@fyi.net>,
>         ···@jules.res.cmu.edu (Greg Schohn) writes:
> > could anybody explain to me why this code has problems deleting the first
> > element of a list when it is selected (it will remove everything else - as
> > I would expect it too)...
> >

As you seem to be aware, #'delete is "destructive", meaning it does not make a
new list, suggesting it alters its list argument, so you expect the list to be
changed, for the first element as well as any other. Wellll...<g>

There is no such thing as a list! There is one cons cell whose cdr points to
another cons cell until some cdr is nil. (If a cdr points to something other
than nil or another cons, you have a dotted list, which I do not want to get
into. :)

When #'delete "finds its target" it has gotten to a cons cell whose car points
to the target. Now, if the cons cell is not the first, #'delete has to re-splice
the list (OK, there /is/ such a thing) by having the /prior/ cdr point to the
ensuing cons. So far so good, except you are probably confused by all that. All
Lisp newbies need to draw pictures of lists with cons cells and cars and cdrs
for a while until that kind of talk becomes natural.

Now here's the problem. The target is found in the first cons. There is no prior
cons to splice with the remainder of the list. There is nothing #'delete can do!
Of course, #'delete also has a responsibility to return the "altered"
list--actually, since there is no such thing as a list, the cons cell heading
the list.

That's a no-brainer if it was nailing a mid-list target, since the cons it was
passed is stll the head of the list. But if the target was first, #'delete does
its job not by splicing but by returning the remainder of the list, ie, the cdr
of the first cons.

In your code, you ignore the value returned by #'delete (as did all of us when
we were newbies!). As another respondent noted, you must always capture
#'delete's return in the event that the target was first. And in your case, that
is especially tough, since it will do you no good to code: (setf l (delete val
l)) since the alteration of the local "l" will not affect the list being passed
to #'next_rnd, and /that/ (wherever it is) is the place where it must be
changed.

You could use multiple return values to return both the (potentially) new lead
cons (aka "list") and the random value, but I think it would be better to just
have #'next_rnd do the picking and the outer code that originated the list
contents do the removing. But that is getting into style.

Cheers,

  Ken
From: Barry Margolin
Subject: Re: delete?
Date: 
Message-ID: <RMPz.27$Ey4.493002@cam-news-reader1.bbnplanet.com>
In article <·················@liii.com>, Ken Tilton  <····@liii.com> wrote:
>Now here's the problem. The target is found in the first cons. There is no prior
>cons to splice with the remainder of the list. There is nothing #'delete can do!
>Of course, #'delete also has a responsibility to return the "altered"
>list--actually, since there is no such thing as a list, the cons cell heading
>the list.

While I'm not aware of any implementations that work this way, there *is*
something DELETE can do in this case.  Here's a simplified implementation
that handles deleting the first element of a list destructively:

(defun delete (object list)
  (cond ((and (consp list)
	      (eq object (first list))
              (consp (setf (rest list)
                           (delete object (rest list)))))
         (setf (first list) (second list))
         (setf (cdr list) (cddr list))
         list)
        ...))

This pulls the second element into the first cons, and then splices out the
second cons.

However, there's still one case where there's nothing DELETE can do: if all
the elements of the list are being deleted, and the result will be NIL.
There's no way that DELETE can turn a cons into NIL.  So you still need to
use the DELETE function for value

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Cambridge, MA
Support the anti-spam movement; see <http://www.cauce.org/>
Please don't send technical questions directly to me, post them to newsgroups.