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

REMF and REMPROP



I would like some clarification on the definition of REMF and REMPROP.
Both of these are documented by CLtL to "destructively splice the
property list" to remove the value.  The nature of the destructive
splicing is not specified.

The question is, is it legal for REMF and REMPROP to remove the pointer
to the value (i.e., by setting it to NIL) as part of this operation?
This is advantageous to some garbage-collection schemes, which
have an easier time collecting the value pointed to if it is
indeed garbage after the REMPROP.

The disadvantage is that the behavior of REMPROP would be undefined
when property lists are shared.  For example, consider the following
sequence:

(SETQ *FOO* (LIST :A '(A GARBAGE) :B '(B GARBAGE)))
(SETQ *ORIGINAL-FOO* *FOO*)
(REMF *FOO* :A)
*FOO*
*ORIGINAL-FOO*

One might expect the last form to return (:A (A GARBAGE) :B (B GARBAGE)), 
whereas if REMF is allowed to bash the pointer to assist garbage
collection, the last form would return (:A NIL :B (B GARBAGE)).

Alternatively, would it be legal for REMF to pull the indicators and
values to the front of the list?  In that case, *ORIGINAL-FOO* would end
up equal to (:B (B GARBAGE)).