Re: delete command weirdness
- From: Nathaniel Calloway <ntc6@xxxxxxxxxxx>
- Date: Tue, 13 May 2008 01:18:20 -0400
CL-USER> (defvar testing)
CL-USER> (setq testing '(a b c d))
(A B C D)
CL-USER> (delete 'a testing)
(B C D)
The (B C D) you see above is the value returned by delete. Obvious,
perhaps, but I am just warming up.
Uh huh....I know how lisp works.
(A B C D)
If you are familiar at all with programming (I do not know how
experienced you are) you will realize delete does not see the
/variable/ testing, the caller pulls a value out of that variable and
passes it to delete. ie, delete sees (a b c d), not "testing".
This is wrong. When you don't try to change the car, it goes to where
testing points to the memory and changes the various cons'es, IE it
"sees" where testing is pointing. Don't confuse this with the
differences in the eval loop between macros and functions.
All delete can do is dutifully return a list without A, and whaddaya
know, it can do just by returning the CDR of the list received (since
A appears only in the car of the first cons).
Well, sure, but that's not the issue. The issue is why it doesn't
change the assignment of testing.
CL-USER> (delete 'b testing)
(A C D)
Now delete is forced to do some work, and makes the cdr of the first
cons the cdr of the second cons, effectively discarding the second
cons from the structure received.
You skipped the last line showing that delete is in fact
destructive...but only when you aren't changing the car.
Another way for you to understand this is to try to write a
destructive version of my-delete that does behave they way you
expected. Methinks the light will go on before you write a line of
My problem isn't writing code, it's understanding why exactly this
behavior was chosen. This is indicative of something deeper in lisp
than anything you have touched on. I'm assuming it has to do with how
variables are assigned. What I fail to understand is why exactly lisp
doesn't have a problem changing where a particular cdr points, but
does have a problem with changing where a variable points. My feeling
is that because variables are handled differently in some way,
whomever coded delete sacrificed consistent behavior for consistent
code. (For the record, if this is the case, I think it is silly:
either smash everything into the same namespace like scheme and treat
it all the same, and have your theoretical consistency, or just make
it work intuitively).
And that brings me to another question: Why even include delete at
all? Remove works just fine in a non-destructive way, and we can
always just (setq testing (remove 'a testing)). Is there any purpose
to having a function that will destructively delete anything but the
car? Perhaps, but I sure can't think of one.