Subject: bug#34708: alist-get has unclear documentation

From: Michael Heerdegen <[email-masked]>
Date: Mon, 04 Mar 2019 19:22:28 +0100

Eric Abrahamsen <[email-masked]> writes:

> While we're here, you mentioned up-thread that REMOVE isn't intuitive
> if you don't understand what the DEFAULT arg is doing. Obviously I
> don't understand that: would you elaborate?

Ok, I try to repeat with different words.  Too many words, sorry.  What
I wanted to say was actually simple.

In most cases what (setf (alist-get KEY ...) ...) should do is clear:
change the association of an existing key, or add a key-value
association.

In case of using the DEFAULT argument - we don't yet speak of setf at all
here -

  (alist-get key alist default)

returns DEFAULT if KEY is not found.  But it also returns DEFAULT if KEY
is found in ALIST and happens to be associated with DEFAULT.

This makes a call like

  (setf (alist-get key alist default) default)

ambiguous: the "goal" (which is making (alist-get key alist default)
eval to DEFAULT) can be reached in two ways: (1) by making KEY being
associated with DEFAULT in ALIST and (2) by removing any existing
association for KEY.

You can choose which behavior you want via the REMOVE argument which
comes after the DEFAULT arg: specifying REMOVE non-nil gives you (2) -
remove it - else you get (1).

BTW, a simpler way to delete an association in an alist is

  (setf (alist-get key alist) nil)

This will do most of the time unless it's important that the alist
doesn't grow too much.  Maybe it's because of this that the remove
facility is a bit hidden.

Michael.