Subject: bug#75170: add-to-alist: new function

From: Juri Linkov <[email-masked]>
Date: Sun, 19 Jan 2025 21:35:00 +0200

> I just noticed: the docstring of alist-get is much more verbose
> regarding how this function can be combined with setf than the elisp
> manual.  So extending the documentation of alist-get in the elisp manual
> can already make a big difference!  Personally, I always find typical
> usage examples in the elisp manual most helpful.

One typical usage example:

  (setf (alist-get 'sentence (alist-get 'c treesit-thing-settings)) '("statement"))

that replaces the value of the 'c' -> 'sentence' keys in

  (setq-local treesit-thing-settings
            '((c . ((sexp (not "[](),[{}]"))
                    (sentence "\\(?:attributed_statement\\)")
                    (text "\\(?:comment\\|raw_string_literal\\)")))))

> Also, it seems to me there is a difference between add-to-alist and
> (setf (alist-get ...)).  It was already Stephen Gildea's original
> proposal from long time ago to give this function an optional arg
> NO-REPLACE, and his proposal included a nice example for when this can
> be useful (copied in my first posting).  It seems to me that
> (setf (alist-get ...)) has no equivalent of NO-REPLACE.  Personally,
> I have not run in a situation when I had needed this arg; but I can
> imagine that it would help others.

Isn't NO-REPLACE equivalent to this:

  (cl-pushnew "statement2" (alist-get 'sentence (alist-get 'c treesit-thing-settings)))

that results in

  ((c (sexp (not "[](),[{}]"))
      (sentence "statement2" "statement")
      (text "\\(?:comment\\|raw_string_literal\\)")))