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)
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
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
scha...@netcom.ca (hs)
>
> 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
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/
(defun next_rnd (l)
(let* ((index (floor(random(length l))))
(val (elt l index)))
(progn (delete val l) (print l) val)))
In article <EnAyE...@fyi.net>,
g...@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)
--
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")
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 <EnAyE...@fyi.net>,
> g...@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
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, bar...@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.