14. Locatives

14.1 Cells and Locatives

A locative is a type of Lisp object used as a pointer to a cell . Locatives are inherently a more "low level" construct than most Lisp objects; they require some knowledge of the nature of the Lisp implementation. Most programmers will never need them. A cell is a machine word which contains a (pointer to a) Lisp object. A symbol has five cells: the print name cell, the value cell, the function cell, the property list cell, and the package cell. The value cell holds (a pointer to) the binding of the symbol, and so on. Also, an array leader of length n has n cells, and an array of n elements has n cells provided the array is not a numeric array. However, a numeric array contains a different kind of cell, which cannot be pointed to by a locative. There are a set of functions which create locatives to cells; the functions are documented with the kind of object to which they create a pointer. See ap-1 , ap-leader , car-location , value-cell-location , etc. The macro locf (see LINK:(locf-fun)) can be used to convert a form which accesses a cell to one which creates a locative pointer to that cell: for example,

(locf (fsymeval x)) ==> (function-cell-location x)
14.2 Functions Which Operate on Locatives
Either of the functions car and cdr (see LINK:(car-fun)) may be given a locative, and will return the contents of the cell at which the locative points.
For example, 
(car (value-cell-location x))
is the same as 
(symeval x)
Similarly, either of the functions rplaca and rplacd may be used to store an object into the cell at which a locative points.
For example, 
(rplaca (value-cell-location x) y)
is the same as 
(set x y)
If you mix locatives and lists, then it matters whether you use car and rplaca or cdr and rplacd , and care is required. For example, this function takes advantage of value-cell-location to cons up a list in forward order without special-case code. The first time through the loop, the rplacd is equivalent to (setq res ...) ; on later times through the loop the rplacd tacks an additional cons onto the end of the list.
(defun sort-of-mapcar (fcn lst)
  (do ((lst lst (cdr lst))
       (res nil)
       (loc (value-cell-location 'res)))
      ((null lst) res)
    (rplacd loc
	    (setq loc (ncons (funcall fcn (car lst)))))))
You might expect this not to work if it was compiled and res was not declared special, since non-special compiled variables are not represented as symbols. However, the compiler arranges for it to work anyway.