unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#75170: add-to-alist: new function
@ 2024-12-29  5:33 Roland Winkler
  2024-12-29  6:34 ` Roland Winkler
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Roland Winkler @ 2024-12-29  5:33 UTC (permalink / raw)
  To: 75170

On Mon, 12 Feb 2001, Stephen Gildea wrote:
> Here's a handy function I'd like to see added to Emacs 21: add-to-alist.
> It is like add-to-list, but it looks only at the cars of the element to
> be added and the existing list elements when considering a match.  An
> additional optional argument to add-to-alist says what to do if the car
> matches but the cdr does not.
> 
> I use this function in my .emacs to update values in alists such as
> default-frame-alist and auto-mode-alist; I'm sure it has other uses.
> My goal in proposing this function is to allow .emacs files to be
> shorter and easier to write.  The functions add-to-list and add-hook
> were important steps in that direction; here is another such step.
> 
> 
> (defun add-to-alist (alist-var elt-cons &optional no-replace)
>   "Add to the value of ALIST-VAR an element ELT-CONS if it isn't there yet.
> If an element with the same car as the car of ELT-CONS is already present,
> replace it with ELT-CONS unless NO-REPLACE is non-nil; if a matching
> element is not already present, add ELT-CONS to the front of the alist.
> The test for presence of the car of ELT-CONS is done with `equal'."
>   (let ((existing-element (assoc (car elt-cons) (symbol-value alist-var))))
>     (if existing-element
>         (or no-replace
>             (rplacd existing-element (cdr elt-cons)))
>       (set alist-var (cons elt-cons (symbol-value alist-var))))))
> 
> 
> The no-replace argument is useful for setting auto-mode-alist when you
> don't know whether Emacs supports a particular programming language.
> For example, the following suppresses using text-mode for m4 files in
> Emacs 19 but doesn't override using m4-mode in Emacs 20.
> 
> (setq default-major-mode 'text-mode)
> (add-to-alist 'auto-mode-alist '("\\.m4\\'" . fundamental-mode) t)

While I thought about a function add-to-alist I found the above thread
from 24 years ago.  Stephen's message describes nicely when such a
function can be useful.  I suggest to add such a function to subr.el.

The code below follows the conventions of add-to-list.

(defun add-to-alist (alist-var elt-cons &optional no-replace append compare-fn)
  "Add ELT-CONS to the value of ALIST-VAR if it isn't there yet.
If an element with the same car as the car of ELT-CONS is already present
in ALIST-VAR, replace it with ELT-CONS unless NO-REPLACE is non-nil.
If a matching element is not yet present, add ELT-CONS at the beginning
of ALIST-VAR.  If APPEND is non-nil, add ELT-CONS at the end of ALIST-VAR.
The test for presence of ELT-CONS is done with `equal', or with COMPARE-FN
if that's non-nil.
ALIST-VAR should not refer to a lexical variable.

The return value is the new value of ALIST-VAR."
  (let ((elt (cond ((or (null compare-fn) (eq compare-fn #'equal))
	            (assoc (car elt-cons) (symbol-value alist-var)))
                   ((eq compare-fn #'eq)
	            (assq (car elt-cons) (symbol-value alist-var)))
                   (t
	            (let ((alist (symbol-value alist-var))
                          (key (car elt-cons)))
	              (while (and alist
                                  (not (funcall compare-fn key (caar alist))))
	                (setq alist (cdr alist)))
                      (car alist))))))
    (if elt
        (progn
          (unless no-replace
            (setcdr elt (cdr elt-cons)))
          (symbol-value alist-var))
      (set alist-var
	   (if append
	       (append (symbol-value alist-var) (list elt-cons))
	     (cons elt-cons (symbol-value alist-var)))))))





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#75170: add-to-alist: new function
  2024-12-29  5:33 bug#75170: add-to-alist: new function Roland Winkler
@ 2024-12-29  6:34 ` Roland Winkler
  2024-12-29  7:54   ` Juri Linkov
  2024-12-29  7:33 ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-12-29  7:50 ` Eli Zaretskii
  2 siblings, 1 reply; 7+ messages in thread
From: Roland Winkler @ 2024-12-29  6:34 UTC (permalink / raw)
  To: 75170

On Sat, Dec 28 2024, Roland Winkler wrote:
> On Mon, 12 Feb 2001, Stephen Gildea wrote:
>> Here's a handy function I'd like to see added to Emacs 21:
>> add-to-alist.

I forgot to say: I could not find any follow-up or discussion of
Stephen's proposal

https://lists.gnu.org/archive/html/bug-gnu-emacs/2001-02/msg00066.html

I know about the very different approaches underlying the function
add-to-list compared to the macro pushnew.  I followed the design of
add-to-list as I am thinking (like Stephen) of similar use cases.





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#75170: add-to-alist: new function
  2024-12-29  5:33 bug#75170: add-to-alist: new function Roland Winkler
  2024-12-29  6:34 ` Roland Winkler
@ 2024-12-29  7:33 ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-12-29  7:50 ` Eli Zaretskii
  2 siblings, 0 replies; 7+ messages in thread
From: Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-12-29  7:33 UTC (permalink / raw)
  To: Roland Winkler; +Cc: 75170

Hello,

Roland Winkler <winkler@gnu.org> writes:

> On Mon, 12 Feb 2001, Stephen Gildea wrote:

[...]

> While I thought about a function add-to-alist I found the above thread
> from 24 years ago.  Stephen's message describes nicely when such a
> function can be useful.  I suggest to add such a function to subr.el.
>
> The code below follows the conventions of add-to-list.
>
> (defun add-to-alist (alist-var elt-cons &optional no-replace append compare-fn)
>   "Add ELT-CONS to the value of ALIST-VAR if it isn't there yet.
> If an element with the same car as the car of ELT-CONS is already present
> in ALIST-VAR, replace it with ELT-CONS unless NO-REPLACE is non-nil.
> If a matching element is not yet present, add ELT-CONS at the beginning
> of ALIST-VAR.  If APPEND is non-nil, add ELT-CONS at the end of ALIST-VAR.
> The test for presence of ELT-CONS is done with `equal', or with COMPARE-FN
> if that's non-nil.
> ALIST-VAR should not refer to a lexical variable.
>
> The return value is the new value of ALIST-VAR."
>   (let ((elt (cond ((or (null compare-fn) (eq compare-fn #'equal))
> 	            (assoc (car elt-cons) (symbol-value alist-var)))
>                    ((eq compare-fn #'eq)
> 	            (assq (car elt-cons) (symbol-value alist-var)))
>                    (t
> 	            (let ((alist (symbol-value alist-var))
>                           (key (car elt-cons)))
> 	              (while (and alist
>                                   (not (funcall compare-fn key (caar alist))))
> 	                (setq alist (cdr alist)))
>                       (car alist))))))
>     (if elt
>         (progn
>           (unless no-replace
>             (setcdr elt (cdr elt-cons)))
>           (symbol-value alist-var))
>       (set alist-var
> 	   (if append
> 	       (append (symbol-value alist-var) (list elt-cons))
> 	     (cons elt-cons (symbol-value alist-var)))))))

FWIW, in my working branch I use alist-set which does something similar,
I think:

--8<---------------cut here---------------start------------->8---
(defun alist-set (key alist value &optional testfn)
  "Associate VALUE with KEY in ALIST, comparing keys with TESTFN."
  (setf (alist-get key alist nil nil testfn) value))
--8<---------------cut here---------------end--------------->8---


Cheers,

Eshel





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#75170: add-to-alist: new function
  2024-12-29  5:33 bug#75170: add-to-alist: new function Roland Winkler
  2024-12-29  6:34 ` Roland Winkler
  2024-12-29  7:33 ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-12-29  7:50 ` Eli Zaretskii
  2024-12-29 14:50   ` Roland Winkler
  2 siblings, 1 reply; 7+ messages in thread
From: Eli Zaretskii @ 2024-12-29  7:50 UTC (permalink / raw)
  To: Roland Winkler; +Cc: 75170

> From: Roland Winkler <winkler@gnu.org>
> Date: Sat, 28 Dec 2024 23:33:56 -0600
> 
> On Mon, 12 Feb 2001, Stephen Gildea wrote:
> > Here's a handy function I'd like to see added to Emacs 21: add-to-alist.
> > It is like add-to-list, but it looks only at the cars of the element to
> > be added and the existing list elements when considering a match.  An
> > additional optional argument to add-to-alist says what to do if the car
> > matches but the cdr does not.
> > 
> > I use this function in my .emacs to update values in alists such as
> > default-frame-alist and auto-mode-alist; I'm sure it has other uses.
> > My goal in proposing this function is to allow .emacs files to be
> > shorter and easier to write.  The functions add-to-list and add-hook
> > were important steps in that direction; here is another such step.
> > 
> > 
> > (defun add-to-alist (alist-var elt-cons &optional no-replace)
> >   "Add to the value of ALIST-VAR an element ELT-CONS if it isn't there yet.
> > If an element with the same car as the car of ELT-CONS is already present,
> > replace it with ELT-CONS unless NO-REPLACE is non-nil; if a matching
> > element is not already present, add ELT-CONS to the front of the alist.
> > The test for presence of the car of ELT-CONS is done with `equal'."
> >   (let ((existing-element (assoc (car elt-cons) (symbol-value alist-var))))
> >     (if existing-element
> >         (or no-replace
> >             (rplacd existing-element (cdr elt-cons)))
> >       (set alist-var (cons elt-cons (symbol-value alist-var))))))
> > 
> > 
> > The no-replace argument is useful for setting auto-mode-alist when you
> > don't know whether Emacs supports a particular programming language.
> > For example, the following suppresses using text-mode for m4 files in
> > Emacs 19 but doesn't override using m4-mode in Emacs 20.
> > 
> > (setq default-major-mode 'text-mode)
> > (add-to-alist 'auto-mode-alist '("\\.m4\\'" . fundamental-mode) t)
> 
> While I thought about a function add-to-alist I found the above thread
> from 24 years ago.  Stephen's message describes nicely when such a
> function can be useful.  I suggest to add such a function to subr.el.
> 
> The code below follows the conventions of add-to-list.
> 
> (defun add-to-alist (alist-var elt-cons &optional no-replace append compare-fn)
>   "Add ELT-CONS to the value of ALIST-VAR if it isn't there yet.
> If an element with the same car as the car of ELT-CONS is already present
> in ALIST-VAR, replace it with ELT-CONS unless NO-REPLACE is non-nil.
> If a matching element is not yet present, add ELT-CONS at the beginning
> of ALIST-VAR.  If APPEND is non-nil, add ELT-CONS at the end of ALIST-VAR.
> The test for presence of ELT-CONS is done with `equal', or with COMPARE-FN
> if that's non-nil.
> ALIST-VAR should not refer to a lexical variable.

Thanks.

What is the advantage of adding this function, given that add-to-list
can be used with alists, and given that alist-get can nowadays be used
as a generalize variable?





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#75170: add-to-alist: new function
  2024-12-29  6:34 ` Roland Winkler
@ 2024-12-29  7:54   ` Juri Linkov
  2024-12-29 14:54     ` Roland Winkler
  0 siblings, 1 reply; 7+ messages in thread
From: Juri Linkov @ 2024-12-29  7:54 UTC (permalink / raw)
  To: Roland Winkler; +Cc: 75170

>>> Here's a handy function I'd like to see added to Emacs 21:
>>> add-to-alist.
>
> I forgot to say: I could not find any follow-up or discussion of
> Stephen's proposal
>
> https://lists.gnu.org/archive/html/bug-gnu-emacs/2001-02/msg00066.html
>
> I know about the very different approaches underlying the function
> add-to-list compared to the macro pushnew.  I followed the design of
> add-to-list as I am thinking (like Stephen) of similar use cases.

While indeed there were no responses to the original message,
other proposed implementations can be found as well, e.g.

https://lists.gnu.org/archive/html/bug-gnu-emacs/2002-04/msg00669.html
https://lists.gnu.org/archive/html/bug-gnu-emacs/2002-04/msg00671.html

Also there are threads discussing 'org--tag-add-to-alist' and
'package--append-to-alist' (renamed from 'package--add-to-alist').





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#75170: add-to-alist: new function
  2024-12-29  7:50 ` Eli Zaretskii
@ 2024-12-29 14:50   ` Roland Winkler
  0 siblings, 0 replies; 7+ messages in thread
From: Roland Winkler @ 2024-12-29 14:50 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 75170

On Sun, Dec 29 2024, Eli Zaretskii wrote:
> What is the advantage of adding this function, given that add-to-list
> can be used with alists, and given that alist-get can nowadays be used
> as a generalize variable?

The advantage I see for also having the function add-to-alist is the
following:

add-to-list checks for the presence of an element in a list.  In the
case of alists, this means it checks for the presence of associations.
You cannot easily modify an existing association with add-to-list.  If
you have an alist with association (foo . bar) and you call add-to-list
with an element (foo . baz), add-to-list will not remove the association
(foo . bar), but the alist will then contain both associations.

add-to-alist checks for the presence of keys and it makes sure that each
key appears only once in an alist.  By default, it replaces the value of
an existing key.  This makes it easy to modify an existing association.
Only with the optional arg NO-REPLACE non-nil, it will preserve an
existing association.

Say, I want in my .emacs file a more complicated association for a key,
and I do not get initially what I want.  I can call add-to-alist
multiple times, till I get what I want.

Is there a simple way to accomplish this in other ways (a way that we
recommend for users in their init file if they do not want to use
customize like me)?

Would it make sense to give this functions a different name if more
often it may be used to modify existing associations in an alist instead
of adding new ones?





^ permalink raw reply	[flat|nested] 7+ messages in thread

* bug#75170: add-to-alist: new function
  2024-12-29  7:54   ` Juri Linkov
@ 2024-12-29 14:54     ` Roland Winkler
  0 siblings, 0 replies; 7+ messages in thread
From: Roland Winkler @ 2024-12-29 14:54 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 75170

On Sun, Dec 29 2024, Juri Linkov wrote:
> Also there are threads discussing 'org--tag-add-to-alist' and
> 'package--append-to-alist' (renamed from 'package--add-to-alist').

My understanding of these functions is that they serve rather different
purposes.  They are not intended to be used in user init files.





^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2024-12-29 14:54 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-29  5:33 bug#75170: add-to-alist: new function Roland Winkler
2024-12-29  6:34 ` Roland Winkler
2024-12-29  7:54   ` Juri Linkov
2024-12-29 14:54     ` Roland Winkler
2024-12-29  7:33 ` Eshel Yaron via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-12-29  7:50 ` Eli Zaretskii
2024-12-29 14:50   ` Roland Winkler

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).