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


With respect to SETF-GETF and REMF, I strongly support
MAKE-EXPLICITLY-VAGUE.  CLtL says about using SETF with GETF:

    ... The effect is to add a new property-value pair, or update an
    existing pair, in the property list kept in the place. ...

It's hard for me to see how, as Larry phrases it, this is ``pretty
explicit'' about what SETF-GETF is supposed to do.  After all, it says
nothing about order of the pairs on the list before and after the
operation, or even that the same list is to be ``kept in the place''
before and after the operation.  With respect to REMF, CLtL says:

    ... The property indicator and the corresponding value are removed
    by destructively splicing the property list ...

This seems clearer at first glance: the obvious interpretation is that
in (REMF place) the plist in left in place after the REMF is EQ to the
plist in place when given to REMF.  But of course if the pair to be
removed is the first pair in the list, then we'll have to do
``splicing'' by shifting CARs forward in the list.  Actually I think
this language was left over from the discussion of REMPROP, but the
discussion of symbol-plists explicitly mentions that ``modifications to
the property list can be recorded by storing back into the property-list
cell of the symbol.''  So I tend interpret this as saying that the lists
in place before and after (REMF place) need not be EQ, but then it's not
clear if ANY restrictions are being place on REMF other than that the
indicator should not be present in the list when REMF is finished. 

In general, I take it from the first and second paragraphs of page 164
that symbol plists and plists referenced with GETF and REMF are intended
to be dealt with in exactly the same way; after all, both types are just
``a memory cell containing a list with an even number (possibly zero) of
elements.''  Further, I see absolutely no restrictions across
list-modifying calls on the order of the pairs in plists, and I think
this is explicitly a data abstraction issue: after a destructive
operation on a plist is performed, you are guaranteed only that the
property list as ``an object with a unique identity'' (p. 164) is
preserved; that is, the memory cell associated with the plist contains a
list of pairs of the right form, but you are guaranteed nothing about
the relationship between that list of pairs and any preceeding lists
that used to be associated with that memory cell.

Consider, for example, a system (such as a program analysis tool) which
stores massive amounts of information (such as who-calls and other usage
info) on the plists of symbols.  This system knows that, of the 300
properties it stores on symbols, it goes through phases (when it's
analyzing a particular function) of referencing only 5 or 6 of them
(relevant to that function) at a time.  It also knows that, whenever
it's about to go into one of these phases, it sets the value of those
properties to some appropriate thing (such as info about the function
being analyzed).  From reading CLtL, I see absolutely no reason why that
system should not be able to redefine SETF-GETF (or SETF-GET) so that a
stored property is always at the front of the resulting plist.

While I am sensitive to concerns about portability of debugged programs,
I think that, with respect to property lists, programmers who expect
behavior from SETF-GETF which accords with manipulations they perform on
the same lists are breaking the plist data abstraction.  They are
implicitly doing what someone (Pavel?) earlier in this discussion
suggested MAKE-EXPLICITLY-DEFINED for SETF-GETF would be tantamount to
doing: insisting that SETF-GETF be implemented using a particular