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

REMF and REMPROP



    Date: Wed, 4 Feb 1987  11:33 EST
    From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>

    On the other hand, it seems to me that it violates the (implicit)
    contract of a destructive operation like REMPROP to take the excised
    piece of list and chop it up into little pieces or to re-use the list
    cells that it snipped out.  The fact that some built-in operation makes
    a destructive change does not necessarily give this operation the right,
    or the necessary global perspective, to decide what is garbage and what
    is not.  Sharing is possible in Common Lisp, and it is the garbage
    collector's job to decide what cons cells can safely be recycled.
    Destructive operations should do what they are documented to do, and no
    more.

I can interpret parts of that paragraph two ways.  One way (the way I
don't want to) is that REMF can go off and bash the value.  That's not
what Andre was suggesting.  He was suggesting only the structure that IS
the property list.  Here's a more explicit example:
	(setq *key* '(a b c)
	      *value* '(x y z)
	      *plist* (list :a 'a *key* *value* :c 'c)
	      *subplist* (cddr *plist*)
	      *subsubplist* (cdr *subplist*))
What happens by doing (remf *plist* *key*)?  Because REMF is destructive
on the PLIST, I think everyone will agree that
	*plist* => (:a a :c c)
I think everyone will also agree that
	*key* => (a b c)
	*value* => (x y z)
because REMF isn't allowed to bash the key or value.  The question is:
What are the values of *subplist* and *subsubplist*?  Possible answers
include:
	*subplist*	((a b c) (x y z) :c c)	;preserve everything
			(nil nil :c c)		;drop pointers to the key and value
			(nil nil)		;drop pointers and bash structure
			(nil)			;ditto, bashing harder
	*subsubplist*	((x y z) :c c)
			(nil :c c)
			(nil)
REMF has not decided what IS garbage, but it has ALLOWED (a b c) and (x
y z) to be garbage if there are no other pointers to them.