From: Nicolas Neuss
Subject: GETF-equivalent for association lists
Date: 
Message-ID: <87isj7kjez.fsf@ortler.iwr.uni-heidelberg.de>
Hello,

I have just written an equivalent of GETF for association lists.  It looks
as follows:

(defun geta (alist key)
  "An analog for GETF for association lists."
  (cdr (assoc key alist)))

(define-setf-expander geta (alist key &environment env)
  "An analog to GETF for association lists."
  (multiple-value-bind (temps vals stores store-form access-form)
      (get-setf-expansion alist env)
    (with-gensyms (keytemp result record maybe-new-record)
      ;; Return the setf expansion for geta
      (values
       `(,@temps ,keytemp ,record ,maybe-new-record)
       `(,@vals
         ,key
         (assoc ,keytemp ,access-form)
         (or ,record (cons ,key nil)))
       (list result)
       `(if ,record
         (setf (cdr ,record) ,result)
         (let ((,(first stores) (cons ,maybe-new-record ,access-form)))
           (setf (cdr ,maybe-new-record) ,result)
           ,store-form
           ,result))
       `(cdr ,maybe-new-record)))))

;;; Testing:
(defparameter *alist* nil)
(setf (geta *alist* :test) 1)
(setf (geta *alist* :hello) 2)
(setf (geta *alist* :test) 3)
(geta *alist* :test)
*alist*

Since this is my first setf-expander, I would be interested in comments
about this code.

And a further question: is there anything besides historical reasons why
something like GETA is not already in the language?

Nicolas.

From: Pascal Costanza
Subject: Re: GETF-equivalent for association lists
Date: 
Message-ID: <buh30m$s2p$1@newsreader2.netcologne.de>
Nicolas Neuss wrote:

> Hello,
> 
> I have just written an equivalent of GETF for association lists.  It looks
> as follows:
> 
> (defun geta (alist key)
>   "An analog for GETF for association lists."
>   (cdr (assoc key alist)))
[...]

> And a further question: is there anything besides historical reasons why
> something like GETA is not already in the language?

I have used association lists to a great extent in two projects, and 
while at first I have thought that something like GETA and (SETF GETA) 
is missing, I have later realized that it doesn't buy you much. In fact, 
if you only use ASSOC and ACONS, your code becomes much more compact.

Here is why.

+ Oftentimes, you want to check whether an association exists or not. 
When GETA returns NIL, this might be because the associated value is NIL 
or because there's no association stored in the list. A good idiom to 
check this is this:

(let ((cons (assoc key alist))
   (when cons (do-something-with (cdr cons))))

It's hard to beat the terseness of this idiom.

+ When you want to associate a new value, ACONS does the job extremely well:

(setf alist (acons new-key new-value alist))

Again, it's hard to beat the terseness of this idiom. (APUSH would have 
been nice, though.)

You may want (SETF GETA) in order to save memory. However, when such 
optimizations start to become important, it's probably better to switch 
to hash tables or some other data structure anyway.

The important question is whether you access the data structure more 
often than udpate it or vice versa. If you don't update it often, then 
ACONS is just fine.


However, I would also be interested to hear something about the 
historical background.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Pascal Bourguignon
Subject: Re: GETF-equivalent for association lists
Date: 
Message-ID: <87oeszskza.fsf@thalassa.informatimago.com>
Pascal Costanza <········@web.de> writes:
> + When you want to associate a new value, ACONS does the job extremely well:
> 
> (setf alist (acons new-key new-value alist))
> 
> Again, it's hard to beat the terseness of this idiom. (APUSH would
> have been nice, though.)
> 
> You may want (SETF GETA) in order to save memory. However, when such
> optimizations start to become important, it's probably better to
> switch to hash tables or some other data structure anyway.
> 
> The important question is whether you access the data structure more
> often than udpate it or vice versa. If you don't update it often, then
> ACONS is just fine.

And also, whether you need to have a mutable alist or not:
(let* ((a (list :e 2.71 :pi 3.14))  (b (acons :pi 3.00 a)))  (not (equal a b)))
this may be a problem.  Of course, another data structure may be more indicated.
 
> However, I would also be interested to hear something about the
> historical background.
> 
> 
> Pascal

-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/