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

Common LISP omissions: Collect, Locatives

We have been using Common LISP and have noticed two  
important omissions in the language.  
  1) Locatives ("LOCF" as found in ZetaLISP). 
  2) A COLLECT macro. 
  A primary reason for locatives would be to create your own  
"hash-on-eq" functions.  Common LISP provides SXHASH which  
hashes on equal.  A serious problem occurs if the keys are  
circular objects. 
  A collect macro would allow the construction of lists  
maintaining the order of creation.  Currently, the only way  
to produce the same effect, would be to use PUSH and the  
NREVERSE.  If the programmer intends to use the partially  
constructed list, it would need to be REVERSEd each time.   
An example of the collection macro could look like: 
(DEFMACRO With-Collection (vars &body body) 
  (LET (collects gensym) 
     (DOLIST (var vars) 
       (SETQ gensym (GENSYM var)) 
       (PUSH gensym (GET var :collect)) 
       (PUSH gensym collects)) 
       `(LET (,@vars ,@collects) 
              ,@(Macroexpand-All body)) 
       (DOLIST (var vars) (POP (GET var :collect))))) 
(DEFMACRO Collect (obj place) 
  (LET ((endptr (CAR (GET place :collect)))) 
    (,place (SETF (CDR ,endptr) (NCONS ,obj)) 
            (SETQ ,endptr (CDR ,endptr))) 
    (T (SETQ ,place (NCONS ,obj)) 
       (SETQ ,endptr ,place)))) 
(DEFUN Macroexpand-All (form &AUX (mac (MACROEXPAND form))) 
  (IF (CONSP form) 
      (CONS (Macroexpand-All (CAR mac)) (Macroexpand-All (CDR mac))) 
  It would be easier to implement the collect macro if a  
function like LOCF existed.  Furthermore, we would not need  
to check the partially constructed list each time to  
determine whether it was still empty (see the COND in  
  ZetaLISP's LOOP macro includes the collect facility, but  
collection should be possible outside of a loop (for  
example, when searching through a graph). 
David Loewenstern
Mark Silbert
Naval Air Development Center, code 7013
Warminster, PA 18974