unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Lispref add-to-list - doc is unnecessary convoluted
@ 2020-12-04  2:17 Arthur Miller
  2020-12-04  2:27 ` Christopher Dimech
                   ` (2 more replies)
  0 siblings, 3 replies; 23+ messages in thread
From: Arthur Miller @ 2020-12-04  2:17 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1758 bytes --]

Function: add-to-list symbol element &optional append compare-fn

    This function sets the variable symbol by consing element onto the old value, if element is not already a member of that value. It returns the resulting list, whether updated or not. The value of symbol had better be a list already before the call. add-to-list uses compare-fn to compare element against existing list members; if compare-fn is nil, it uses equal.

    Normally, if element is added, it is added to the front of symbol, but if the optional argument append is non-nil, it is added at the end.

    The argument symbol is not implicitly quoted; add-to-list is an ordinary function, like set and unlike setq. Quote the argument yourself if that is what you want.

    Do not use this function when symbol refers to a lexical variable. 

I think this doc is unnecessary convoluted and I don't see reason why it
describes the implementation. That first sentence make something so
simple as add-to-list sound so complicated for some reason when you read
it, and requires one to think twice through what it say (at least me).

Other functions does not do so, so why this one? I don't think it is
necessary since docs anyway says how it add to list (front/back) kist a
three sentences further. 

I think it is more clear to use word 'list' instead of 'symbol' (element
is a symbol too for example). Not least because docs later says: "better
be a list". It clarifies intentions, and hopefully removes the need to say
things like 'better be a list'.

I hope I don't hurt anyone's feelings; I dont' know who wrote it, but I
would like to suggest a slight modification, patch included. I am not
native english speaker, so if you agree to change it, somebody please
look through it.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: add-to-list-doc.patch --]
[-- Type: text/x-patch, Size: 1787 bytes --]

diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi
index ae793d5e15..c7f6a46aeb 100644
--- a/doc/lispref/lists.texi
+++ b/doc/lispref/lists.texi
@@ -761,22 +761,19 @@ List Variables
 
   Two functions modify lists that are the values of variables.
 
-@defun add-to-list symbol element &optional append compare-fn
-This function sets the variable @var{symbol} by consing @var{element}
-onto the old value, if @var{element} is not already a member of that
-value.  It returns the resulting list, whether updated or not.  The
-value of @var{symbol} had better be a list already before the call.
-@code{add-to-list} uses @var{compare-fn} to compare @var{element}
-against existing list members; if @var{compare-fn} is @code{nil}, it
-uses @code{equal}.
+@defun add-to-list list element &optional append compare-fn
+This function adds the @var{element} to a list @var{list} if
+@var{element} is not already a member of that value.  It returns the
+resulting list, whether updated or not.  @code{add-to-list} uses
+@var{compare-fn} to compare @var{element}  against existing list
+members; if @var{compare-fn} is @code{nil}, it uses @code{equal}.
 
 Normally, if @var{element} is added, it is added to the front of
-@var{symbol}, but if the optional argument @var{append} is
+@var{list}, but if the optional argument @var{append} is
 non-@code{nil}, it is added at the end.
 
-The argument @var{symbol} is not implicitly quoted; @code{add-to-list}
-is an ordinary function, like @code{set} and unlike @code{setq}.  Quote
-the argument yourself if that is what you want.
+The argument @var{list} is not implicitly quoted; @code{add-to-list}
+is an ordinary function, like @code{set} and unlike @code{setq}.
 
 Do not use this function when @var{symbol} refers to a lexical
 variable.

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

* Re: Lispref add-to-list - doc is unnecessary convoluted
  2020-12-04  2:17 Lispref add-to-list - doc is unnecessary convoluted Arthur Miller
@ 2020-12-04  2:27 ` Christopher Dimech
  2020-12-04  2:36 ` Robin Tarsiger
  2020-12-04  8:29 ` Eli Zaretskii
  2 siblings, 0 replies; 23+ messages in thread
From: Christopher Dimech @ 2020-12-04  2:27 UTC (permalink / raw)
  To: Arthur Miller; +Cc: emacs-devel

> Sent: Friday, December 04, 2020 at 3:17 AM
> From: "Arthur Miller" <arthur.miller@live.com>
> To: emacs-devel@gnu.org
> Subject: Lispref add-to-list - doc is unnecessary convoluted
>
> Function: add-to-list symbol element &optional append compare-fn
>
>     This function sets the variable symbol by consing element onto the old value, if element is not already a member of that value. It returns the resulting list, whether updated or not. The value of symbol had better be a list already before the call. add-to-list uses compare-fn to compare element against existing list members; if compare-fn is nil, it uses equal.
>
>     Normally, if element is added, it is added to the front of symbol, but if the optional argument append is non-nil, it is added at the end.
>
>     The argument symbol is not implicitly quoted; add-to-list is an ordinary function, like set and unlike setq. Quote the argument yourself if that is what you want.
>
>     Do not use this function when symbol refers to a lexical variable.
>
> I think this doc is unnecessary convoluted and I don't see reason why it
> describes the implementation. That first sentence make something so
> simple as add-to-list sound so complicated for some reason when you read
> it, and requires one to think twice through what it say (at least me).

I concur.

> Other functions does not do so, so why this one? I don't think it is
> necessary since docs anyway says how it add to list (front/back) kist a
> three sentences further.
>
> I think it is more clear to use word 'list' instead of 'symbol' (element
> is a symbol too for example). Not least because docs later says: "better
> be a list". It clarifies intentions, and hopefully removes the need to say
> things like 'better be a list'.

Agree

> I hope I don't hurt anyone's feelings; I dont' know who wrote it, but I
> would like to suggest a slight modification, patch included. I am not
> native english speaker, so if you agree to change it, somebody please
> look through it.

Not hurt.  I shall read it and report back.

Cheers
C*



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

* Re: Lispref add-to-list - doc is unnecessary convoluted
  2020-12-04  2:17 Lispref add-to-list - doc is unnecessary convoluted Arthur Miller
  2020-12-04  2:27 ` Christopher Dimech
@ 2020-12-04  2:36 ` Robin Tarsiger
  2020-12-04  3:29   ` Arthur Miller
  2020-12-04  3:35   ` Arthur Miller
  2020-12-04  8:29 ` Eli Zaretskii
  2 siblings, 2 replies; 23+ messages in thread
From: Robin Tarsiger @ 2020-12-04  2:36 UTC (permalink / raw)
  To: Arthur Miller; +Cc: emacs-devel

Arthur Miller wrote:
> I think it is more clear to use word 'list' instead of 'symbol' (element
> is a symbol too for example). Not least because docs later says: "better
> be a list". It clarifies intentions, and hopefully removes the need to say
> things like 'better be a list'.

The first argument is not itself a list. The value (as in symbol-value) of
the first argument is expected to be a list. The first sentence of the
documentation has that many levels of indirection because that's how many
levels of indirection there actually are in the behavior of the function.
Your new text does not describe it correctly.

"cons onto" a list is more specific than "add to" in terms of where the new
element winds up, though the paragraph describing the APPEND argument
also mentions this, so it's not strictly necessary.

But while looking at this, I notice that the C-h f docstring for add-to-list
that I see on my Emacs names the first argument more clearly as LIST-VAR
(neither the correct-but-overbroad SYMBOL nor the incorrect LIST), and has
the first sentence "Add ELEMENT to the value of LIST-VAR if it isn't there
yet", which seems to hit both of the points you're dissatisfied with.
Might that be a better starting point if making the elisp Info entry
more readable is desired?

-RTT



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

* Re: Lispref add-to-list - doc is unnecessary convoluted
  2020-12-04  2:36 ` Robin Tarsiger
@ 2020-12-04  3:29   ` Arthur Miller
  2020-12-04  3:35   ` Arthur Miller
  1 sibling, 0 replies; 23+ messages in thread
From: Arthur Miller @ 2020-12-04  3:29 UTC (permalink / raw)
  To: Robin Tarsiger; +Cc: emacs-devel

Robin Tarsiger <rtt@dasyatidae.com> writes:

> Arthur Miller wrote:
>> I think it is more clear to use word 'list' instead of 'symbol' (element
>> is a symbol too for example). Not least because docs later says: "better
>> be a list". It clarifies intentions, and hopefully removes the need to say
>> things like 'better be a list'.
>
> The first argument is not itself a list. The value (as in symbol-value) of
> the first argument is expected to be a list. The first sentence of the
> documentation has that many levels of indirection because that's how many
> levels of indirection there actually are in the behavior of the
> function.
> Your new text does not describe it correctly.
Ok, I agree; my explanation is not that pedantic as you are describing
it; thank you for pointing it out, I wasn't so pedantic when I was
thinking about it, even if implicitly understand it is so. However, I
must ask is that distinction important in this particular case? I
understand you think so; but if you think twice or maybe three time?

I am not an lisp expert, and obivously I needed to look up exactly how
the thing worked, so I red it, despite being using it for very long now;
and I will try to explain how I percieve the issue:

This pedantic treatize of the language, which is more correct than what
I use, is surely correct and has merits, but is it necessary for the end
user; in this particular case? I think that pedancy in this case adds
more confusion then clarification.

I think that conceptually we think of adding to a list, not to a symbol
or to a list-var. At least me. The function name itself suggests we are
adding to a list. When we add to a linked list in C, we are actually
copying a value of an address into some other address in memory; but we
use term "add to list", because that term let us reason in terms of
higher abstraction. In this case cons is the primitve, symbol is our
pointer; so what is wrong to reason about that operation in higher
abstraction as of adding to the list?

I don't think LIST-VAR sounds much better (or worse), per se. It sounds
better in combination with "to the value of":

"Add ELEMENT to the value of LIST-VAR if it isn't there yet"

Maybe that should be in lispref docs instead; entire sentence. It is still
more clear than the current version. In my opinion. Opinions are subjective
:-).


> "cons onto" a list is more specific than "add to" in terms of where the new
> element winds up,
I agree that "cons onto" is more specific to how the operation is
implemented; but I don't think it is necessary for the user of the API,
nor is actually position really necessary; it just says "adds"; but as
you self note, it is mentioned afterwards anyway, which was one of
reasons I reflect over it.

We can add it to the comment below the function, where it shows alternative
implementation. I can agree that it is illustrative and more of a
"tutorial approach" so we don't need to throw it away completely; but I
think it is also important to be clear and concise, especially in the
opening to a function, which add-to-list is not. I can rewrite and add
that info to the end.

> But while looking at this, I notice that the C-h f docstring for add-to-list
> that I see on my Emacs names the first argument more clearly as LIST-VAR
> (neither the correct-but-overbroad SYMBOL nor the incorrect LIST), and has
> the first sentence "Add ELEMENT to the value of LIST-VAR if it isn't there
> yet", which seems to hit both of the points you're dissatisfied with.
> Might that be a better starting point if making the elisp Info entry
> more readable is desired?
It is always desired to make any programming documentation more
readable! :-).




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

* Re: Lispref add-to-list - doc is unnecessary convoluted
  2020-12-04  2:36 ` Robin Tarsiger
  2020-12-04  3:29   ` Arthur Miller
@ 2020-12-04  3:35   ` Arthur Miller
  2020-12-04  8:35     ` Lars Ingebrigtsen
  1 sibling, 1 reply; 23+ messages in thread
From: Arthur Miller @ 2020-12-04  3:35 UTC (permalink / raw)
  To: Robin Tarsiger; +Cc: emacs-devel

Robin Tarsiger <rtt@dasyatidae.com> writes:

> Arthur Miller wrote:
>> I think it is more clear to use word 'list' instead of 'symbol' (element
>> is a symbol too for example). Not least because docs later says: "better
>> be a list". It clarifies intentions, and hopefully removes the need to say
>> things like 'better be a list'.
>
> The first argument is not itself a list. The value (as in symbol-value) of
> the first argument is expected to be a list. The first sentence of the
> documentation has that many levels of indirection because that's how many
> levels of indirection there actually are in the behavior of the function.
> Your new text does not describe it correctly.
Indeed after thinking more, I agree, the value should be a list; It
might be important to point it out :-). Sorry :-)

But can we express it somewhat simpler? LIST-VALUE? Is it more
descriptive than SYMBOL or LIST-VAR.



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

* Re: Lispref add-to-list - doc is unnecessary convoluted
  2020-12-04  2:17 Lispref add-to-list - doc is unnecessary convoluted Arthur Miller
  2020-12-04  2:27 ` Christopher Dimech
  2020-12-04  2:36 ` Robin Tarsiger
@ 2020-12-04  8:29 ` Eli Zaretskii
  2020-12-04 15:28   ` Arthur Miller
  2 siblings, 1 reply; 23+ messages in thread
From: Eli Zaretskii @ 2020-12-04  8:29 UTC (permalink / raw)
  To: Arthur Miller; +Cc: emacs-devel

> From: Arthur Miller <arthur.miller@live.com>
> Date: Fri, 04 Dec 2020 03:17:19 +0100
> 
> +This function adds the @var{element} to a list @var{list} if

This will produce "... to a list LIST if ...", which is sub-optimal.

You omitted the part where the current doc string warns against an
argument that is not a list, and that's losing information.

> -The argument @var{symbol} is not implicitly quoted; @code{add-to-list}
> -is an ordinary function, like @code{set} and unlike @code{setq}.  Quote
> -the argument yourself if that is what you want.
> +The argument @var{list} is not implicitly quoted; @code{add-to-list}
> +is an ordinary function, like @code{set} and unlike @code{setq}.

Not sure why you want to drop the explicit suggestion to quote the
list symbol here: it's also losing information.



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

* Re: Lispref add-to-list - doc is unnecessary convoluted
  2020-12-04  3:35   ` Arthur Miller
@ 2020-12-04  8:35     ` Lars Ingebrigtsen
  0 siblings, 0 replies; 23+ messages in thread
From: Lars Ingebrigtsen @ 2020-12-04  8:35 UTC (permalink / raw)
  To: Arthur Miller; +Cc: Robin Tarsiger, emacs-devel

Arthur Miller <arthur.miller@live.com> writes:

> But can we express it somewhat simpler? LIST-VALUE? Is it more
> descriptive than SYMBOL or LIST-VAR.

But it is a symbol.  The description of the function is awkward because
it's a really weird function.

Comparing it with a more traditional function illustrates the
difference:

(setq foo '(3 2))

(add-to-list 'foo 1)

(cons 1 foo)

`add-to-list' takes a symbol as a parameter.  `cons' takes a list as a
parameter.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no



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

* Re: Lispref add-to-list - doc is unnecessary convoluted
  2020-12-04  8:29 ` Eli Zaretskii
@ 2020-12-04 15:28   ` Arthur Miller
  2020-12-04 15:56     ` Robin Tarsiger
  2020-12-04 17:03     ` Lispref add-to-list - doc is unnecessary convoluted Drew Adams
  0 siblings, 2 replies; 23+ messages in thread
From: Arthur Miller @ 2020-12-04 15:28 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Arthur Miller <arthur.miller@live.com>
>> Date: Fri, 04 Dec 2020 03:17:19 +0100
>> 
>> +This function adds the @var{element} to a list @var{list} if
>
> This will produce "... to a list LIST if ...", which is sub-optimal.
>
> You omitted the part where the current doc string warns against an
> argument that is not a list, and that's losing information.
Yes, it was on purpose, partly because hopefully the argument name LIST is
self-documenting and partly because name of the function says
add-to-list which is self-documenting too. Partly because I also dislike
the wording: "better be a list". Does not sound so proffsy to me; but we
can add description for the argument, and change name to LIST-VAR as
suggested. Maybe the argument should be called LIST-NAME

Another question, why doesn't add-to-list take a list value, why symbol?
Maybe I don't understand lisp enough, but why is this not desirable:

(add-to-list '(1 2 3) '4) or (add-to-list (list 1 2 3) 4)

>> -The argument @var{symbol} is not implicitly quoted; @code{add-to-list}
>> -is an ordinary function, like @code{set} and unlike @code{setq}.  Quote
>> -the argument yourself if that is what you want.
>> +The argument @var{list} is not implicitly quoted; @code{add-to-list}
>> +is an ordinary function, like @code{set} and unlike @code{setq}.
>
> Not sure why you want to drop the explicit suggestion to quote the
> list symbol here: it's also losing information.
Mostly because I think it is rather description of implementation and
also because I dislike the wording:

"Quote the argument yourself if that is what you want."

"If that is I want"? :-) If I don't want - is it not needed then? :-)

Is LIST-NAME ok suggestion? And I can put back info about it's value and
quote. Will have to do it tomorrow though.



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

* Re: Lispref add-to-list - doc is unnecessary convoluted
  2020-12-04 15:28   ` Arthur Miller
@ 2020-12-04 15:56     ` Robin Tarsiger
  2020-12-04 16:14       ` Ad-hoc list structure tutorializing (was: Lispref add-to-list - doc is unnecessary convoluted) Robin Tarsiger
  2020-12-04 17:03     ` Lispref add-to-list - doc is unnecessary convoluted Drew Adams
  1 sibling, 1 reply; 23+ messages in thread
From: Robin Tarsiger @ 2020-12-04 15:56 UTC (permalink / raw)
  To: Arthur Miller; +Cc: emacs-devel

Arthur Miller wrote:
> Another question, why doesn't add-to-list take a list value, why symbol?
> Maybe I don't understand lisp enough, but why is this not desirable:
> 
> (add-to-list '(1 2 3) '4) or (add-to-list (list 1 2 3) 4)

Because that is not how lists work in Lisp. The idea of a "mutable list"
as a conceptual unit does not fall naturally out of the cons-cell-based
formulation of them. If we were in Python or Java, for instance, a
variable would store a reference to a mutable list object, and passing
the mutable list object into a function to mutate it would be an
acceptable style. But what add-to-list does is construct a new list
(if needed) and store it back into the original location. Lists are
mostly processed without mutation, with any "non-consing" in-place
mutation functions being secondary and not covering all the operations.

(To preempt "Isn't this horribly inefficient?": no, in part because
"adding to" the head of a list involves allocating one cons cell and
the rest of the list is structurally incorporated rather than copied.)

The point where it _sets a variable with a specified name_ in order to
do the mutation is very important both in terms of it being clear what
side effects arise. It does this because add-to-list is intended for
conveniently registering unique entries in lists that are part of global
(or buffer-local) state. For general list manipulation, the docstring
explicitly calls out "please do not abuse it in Elisp code, where you
are usually better off using ‘push’ or ‘cl-pushnew’".

It is not just an "implementation detail". The symbol is not the list.
The variable is not the list. "list" already means something and it
is not that.

LIST-NAME would be potentially sane if everything else had already
used -NAME, but I doubt it's stylistically appropriate. -VAR is clear:
you use it mainly in conjunction with symbols that are set up using defvar.

Calling out the part where it's not setq-like explicitly is useful because
many forms that operate on variables _are_ setq-like, and in particular the
alternatives of push and cl-pushnew are both setq-like and treat the
place argument specially.

> "If that is I want"? :-) If I don't want - is it not needed then? :-)

Consider:

  (add-to-list (make-local-variable 'some-lovely-config-list)
     '(happy config entry here))

along the lines of the (set (make-local-variable ...) ...) idiom, to
say "do this mutation buffer-locally, by ensuring that the variable
is buffer-local first, without repeating the variable name". This is
not something you can do with the setq-like forms.

-RTT



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

* Re: Ad-hoc list structure tutorializing (was: Lispref add-to-list - doc is unnecessary convoluted)
  2020-12-04 15:56     ` Robin Tarsiger
@ 2020-12-04 16:14       ` Robin Tarsiger
  2020-12-04 20:24         ` Ad-hoc list structure tutorializing Stefan Monnier
  2020-12-04 22:47         ` Sv: Ad-hoc list structure tutorializing (was: Lispref add-to-list - doc is unnecessary convoluted) arthur miller
  0 siblings, 2 replies; 23+ messages in thread
From: Robin Tarsiger @ 2020-12-04 16:14 UTC (permalink / raw)
  To: Arthur Miller; +Cc: emacs-devel

Robin Tarsiger wrote:
> Arthur Miller wrote:
>> Maybe I don't understand lisp enough, but why is this not desirable:
>>
>> (add-to-list '(1 2 3) '4) or (add-to-list (list 1 2 3) 4)
>
> [...] For general list manipulation, the docstring
> explicitly calls out "please do not abuse it in Elisp code, where you
> are usually better off using ‘push’ or ‘cl-pushnew’".

To be abundantly clear on this, by the way, the non-mutating version
of that (without APPEND) is just the cons primitive itself:

  (cons 4 '(1 2 3))
  => (4 1 2 3)

and when APPEND is set, it's almost equivalent to, well, append:

  (append '(1 2 3) (list 4))
  => (1 2 3 4)

What those don't do is store the new list back where the old one
came from, which is where push and cl-pushnew come in for
local-variable/general-programming purposes and where add-to-list
comes in for config-variable-like purposes. The names are something
of a mishmash, admittedly, I imagine for historical reasons.

Note that you can try to "modify" the tail of a list with nconc:

  (let ((x '(1 2 3)))
    (nconc x (list 4)) ;; wrong! see below
    x)
  => (1 2 3 4)

... but you still need the store-back in general, because
the empty list has no cons cells to mutate!

  (let ((x '()))
    (nconc x (list 4)) ;; oops
    x)
  => nil

so that's only usable as an "optimization" in narrow cases where
you need fast append and can arrange the right guarantees about
the actual list structure, including that no other code is going
to be holding onto any of the sublists at the same time (else
they get a nasty surprise). Don't do that without a really good
reason.

(Aside: why not replace add-to-list with cl-pushnew always? Aside
from historical reasons and things like the buffer-local variable
idiom, being able to toggle APPEND is useful when list entries are
going to be processed in a specific order.)

-RTT



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

* RE: Lispref add-to-list - doc is unnecessary convoluted
  2020-12-04 15:28   ` Arthur Miller
  2020-12-04 15:56     ` Robin Tarsiger
@ 2020-12-04 17:03     ` Drew Adams
  2020-12-04 17:24       ` arthur miller
  1 sibling, 1 reply; 23+ messages in thread
From: Drew Adams @ 2020-12-04 17:03 UTC (permalink / raw)
  To: Arthur Miller, Eli Zaretskii; +Cc: emacs-devel

> why doesn't add-to-list take a list value, why symbol?

That's its specific purpose: update the value
of a (list-valued) _variable_.  It's all about
a variable - updating its value.

The doc is very clear:

https://www.gnu.org/software/emacs/manual/html_node/elisp/List-Variables.html

Please read the entire topic (node).



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

* RE: Lispref add-to-list - doc is unnecessary convoluted
  2020-12-04 17:03     ` Lispref add-to-list - doc is unnecessary convoluted Drew Adams
@ 2020-12-04 17:24       ` arthur miller
  2020-12-04 18:02         ` Drew Adams
  0 siblings, 1 reply; 23+ messages in thread
From: arthur miller @ 2020-12-04 17:24 UTC (permalink / raw)
  To: Drew Adams, Eli Zaretskii; +Cc: emacs-devel@gnu.org

[-- Attachment #1: Type: text/plain, Size: 975 bytes --]

I don't Think it is :-) Tham Magne name should be hänger to add-to-list-symbol :-).

I understand the obvious, I am reflecting over unnecessary convoluted explanation, and probably the design.

Was it necessary for some reason that I don't understand to design this function this way? Or could have just taken a list from the very beginning?



-------- Originalmeddelande --------
Från: Drew Adams <drew.adams@oracle.com>
Datum: 2020-12-04 18:04 (GMT+01:00)
Till: Arthur Miller <arthur.miller@live.com>, Eli Zaretskii <eliz@gnu.org>
Kopia: emacs-devel@gnu.org
Ämne: RE: Lispref add-to-list - doc is unnecessary convoluted

> why doesn't add-to-list take a list value, why symbol?

That's its specific purpose: update the value
of a (list-valued) _variable_.  It's all about
a variable - updating its value.

The doc is very clear:

https://www.gnu.org/software/emacs/manual/html_node/elisp/List-Variables.html

Please read the entire topic (node).

[-- Attachment #2: Type: text/html, Size: 1853 bytes --]

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

* RE: Lispref add-to-list - doc is unnecessary convoluted
  2020-12-04 17:24       ` arthur miller
@ 2020-12-04 18:02         ` Drew Adams
  0 siblings, 0 replies; 23+ messages in thread
From: Drew Adams @ 2020-12-04 18:02 UTC (permalink / raw)
  To: arthur miller, Eli Zaretskii; +Cc: emacs-devel

> > > why doesn't add-to-list take a list value, why symbol?
> >
> > That's its specific purpose: update the value
> > of a (list-valued) _variable_.  It's all about
> > a variable - updating its value.
> >
> > The doc is very clear:
> > https://www.gnu.org/software/emacs/manual/html_node/elisp/List-Variables.html
> >
> > Please read the entire topic (node).
>
> I understand the obvious

I'm not sure you do.  Or maybe it's not so obvious.

I suggest you read that manual node again.  I'm not
talking about the doc string.  It's important to
read about all of what's in that node, as the things
presented are related - you can compare and contrast
them to better understand what each is for (what it
does).

> Was it necessary for some reason that I don't
> understand to design this function this way?
> Or could have just taken a list from the very beginning?

It's not about modifying a list.  And it's not about
consing an element onto a list.  It's about consing
an element onto a list that is the value of a
_variable_ and reassigning that variable to the
result.

A function that takes only a list as arg has no way
of assigning any value to a _variable_.

This function (and it is a function, unlike, say,
`setq') takes a _symbol_ as arg - a symbol whose
value as a _variable_ is a list.  And it returns
the same symbol, after changing its value to be a
list that has the argument value as car and the
original value (list) as cdr.

That's all.

You can compare it with the macro `push', if you
like.  That macro has, as its second arg, a _place_,
which can be, for example, a variable.  It adds a
value to the list that's stored in the place.

If the place is a variable then that list is the
value of the variable.  For a variable, `push'
thus updates the value of a list-valued variable
to be a list whose car is the argument value and
whose cdr is the original value (list).

The essential difference between `add-to-list'
and `push' (in the case of pushing to a variable
place) is that the former is a function and the
latter is a macro.  You can pass a sexp as first
arg to `add-to-list', and it gets _evaluated_ to
provide the variable to use.



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

* Re: Ad-hoc list structure tutorializing
  2020-12-04 16:14       ` Ad-hoc list structure tutorializing (was: Lispref add-to-list - doc is unnecessary convoluted) Robin Tarsiger
@ 2020-12-04 20:24         ` Stefan Monnier
  2020-12-04 21:12           ` Christopher Dimech
  2020-12-04 21:40           ` add-to-list vs cl-pushnew Robin Tarsiger
  2020-12-04 22:47         ` Sv: Ad-hoc list structure tutorializing (was: Lispref add-to-list - doc is unnecessary convoluted) arthur miller
  1 sibling, 2 replies; 23+ messages in thread
From: Stefan Monnier @ 2020-12-04 20:24 UTC (permalink / raw)
  To: Robin Tarsiger; +Cc: Arthur Miller, emacs-devel

> (Aside: why not replace add-to-list with cl-pushnew always?

Good question.


        Stefan "who really doesn't like `add-to-list`"




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

* Re: Ad-hoc list structure tutorializing
  2020-12-04 20:24         ` Ad-hoc list structure tutorializing Stefan Monnier
@ 2020-12-04 21:12           ` Christopher Dimech
  2020-12-05  7:45             ` Eli Zaretskii
  2020-12-06  5:39             ` Richard Stallman
  2020-12-04 21:40           ` add-to-list vs cl-pushnew Robin Tarsiger
  1 sibling, 2 replies; 23+ messages in thread
From: Christopher Dimech @ 2020-12-04 21:12 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Arthur Miller, Robin Tarsiger, emacs-devel

> Sent: Friday, December 04, 2020 at 9:24 PM
> From: "Stefan Monnier" <monnier@iro.umontreal.ca>
> To: "Robin Tarsiger" <rtt@dasyatidae.com>
> Cc: "Arthur Miller" <arthur.miller@live.com>, emacs-devel@gnu.org
> Subject: Re: Ad-hoc list structure tutorializing
>
> > (Aside: why not replace add-to-list with cl-pushnew always?
>
> Good question.
>
>
>         Stefan "who really doesn't like `add-to-list`"
>

Eli?



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

* Re: add-to-list vs cl-pushnew
  2020-12-04 20:24         ` Ad-hoc list structure tutorializing Stefan Monnier
  2020-12-04 21:12           ` Christopher Dimech
@ 2020-12-04 21:40           ` Robin Tarsiger
  2020-12-04 21:51             ` Robin Tarsiger
  1 sibling, 1 reply; 23+ messages in thread
From: Robin Tarsiger @ 2020-12-04 21:40 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

Stefan Monnier wrote:
>> (Aside: why not replace add-to-list with cl-pushnew always?
> 
> Good question.
> 
> 
>         Stefan "who really doesn't like `add-to-list`"

In case it was interpreted differently, my original question was
rhetorical. There's several reasons I can think of to keep using
add-to-list's current behavior as-is for its primary use case,
as opposed to recommending that new code avoid it entirely:

  - The unquoted variable name argument leaving available the
    make-local-variable idiom and similar.

  - The presence of the APPEND arg. This being a toggle lets it
    be plumbed through wrapper functions easily, so that you can
    write (defun foo-add-bar (bar &optional at-end) ...) and call
    (add-to-list 'foo-bar-list rectified-bar at-end) from it.

  - The use of equal, not eql, as the default comparison function.
    This becomes important if any of the list variables contain
    almost anything other than symbols, and I could see eql as a
    default in this case leading to subtle bugs since duplicates
    wouldn't be common, nor necessarily punished in practice.
    (eql "foo" "foo") is allowed to be nil.

  - The docstring mentioning the potential need for eval-after-load
    to handle package ordering issues, which is an easy source of
    bugs in add-to-list's main use case but irrelevant in most
    list processing. If you just use the general list processing
    functions, there isn't as good a place to warn about that.

  - I recall a while ago that pulling in the cl library for one
    or two symbols was considered bad style because it was quite
    heavy, but I don't know if that's still true.

However, I would not be averse to finding it a better primary name
and demoting the add-to-list name to being a compatibility alias,
especially if new elisp programmers are likely to stumble into it
and skip over the the "please do not abuse for general list
manipulation" part of the doc, since the name itself both doesn't
imply that right now and is paradoxically easier to find than the
push family by some (albeit not-so-good) routes. If you do this,
you'd want to hit add-to-ordered-list too.

I also think upon looking at the "List Variables" section again
that it could usefully be split up, since putting push and
add-to-list right next to each other when the latter is so much
more specialized could be structurally misleading. (The "please
do not abuse" text is also nowhere there, instead obscured behind
"Do not use this function when SYMBOL refers to a lexical
variable.", which could lead off into the weeds of e.g. "ah,
so if I want to use this function on locals then I have to not
use lexical-binding" to someone not already receiving usage
cues from other places.)

-RTT



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

* Re: add-to-list vs cl-pushnew
  2020-12-04 21:40           ` add-to-list vs cl-pushnew Robin Tarsiger
@ 2020-12-04 21:51             ` Robin Tarsiger
  0 siblings, 0 replies; 23+ messages in thread
From: Robin Tarsiger @ 2020-12-04 21:51 UTC (permalink / raw)
  To: emacs-devel

Robin Tarsiger wrote:
>   - The unquoted variable name argument leaving available the
>     make-local-variable idiom and similar.

On rethinking, I realize that this is subtly wrong for many
such variables, because future global additions won't propagate
inward. So I retract that item for now. Oops.

-RTT



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

* Sv: Ad-hoc list structure tutorializing (was: Lispref add-to-list - doc is unnecessary convoluted)
  2020-12-04 16:14       ` Ad-hoc list structure tutorializing (was: Lispref add-to-list - doc is unnecessary convoluted) Robin Tarsiger
  2020-12-04 20:24         ` Ad-hoc list structure tutorializing Stefan Monnier
@ 2020-12-04 22:47         ` arthur miller
  1 sibling, 0 replies; 23+ messages in thread
From: arthur miller @ 2020-12-04 22:47 UTC (permalink / raw)
  To: Robin Tarsiger; +Cc: emacs-devel@gnu.org

[-- Attachment #1: Type: text/plain, Size: 6083 bytes --]

What those don't do is store the new list back where the old one
came from, which is where push and cl-pushnew come in for
local-variable/general-programming purposes and where add-to-list
comes in for config-variable-like purposes. The names are something
of a mishmash, admittedly, I imagine for historical reasons.

Note that you can try to "modify" the tail of a list with nconc:

  (let ((x '(1 2 3)))
    (nconc x (list 4)) ;; wrong! see below
    x)
  => (1 2 3 4)

... but you still need the store-back in general, because
the empty list has no cons cells to mutate!

  (let ((x '()))
    (nconc x (list 4)) ;; oops
    x)
  => nil

so that's only usable as an "optimization" in narrow cases where
you need fast append and can arrange the right guarantees about
the actual list structure, including that no other code is going
to be holding onto any of the sublists at the same time (else
they get a nasty surprise).
______________________________________________________
What you describe is something similar to how I came to read the
docs yesterday.

I have a buffer local variable which is a list of lists. Every list is a lambda.
Some of lambdas will be added to after-init-hook in Emacs, some to some
other mode hooks. What I am tryingis to merge them all small lambdas
belonging to certain hook into one bigger lambda, or their bodies so to say.

So I am traversing this buffer local variable, and trying to nconc and setcar
and setcdr stuff to achieve the goal, and the problem I stumbled upon was
exactly that the end result (concatenated lambad) was always in some local
variable that went out of the scope somehow. I removed let and tried to
instead defvar local variables I needed instead, however I haven't got time yet
to work on it more. But what you explain seems to be what I discovered  🙂.

Your explanation make me understand why  the function is design so, and what
is the purpose.

However that is just a side note. It is not add-to-list fault, nor it's documentation.

While I agree with what you say and understand how it works, what bothers me
is that documentation encapsulates too many low-level details. We have to
think about the audience. I am quite sure that you, Drew, Eli or monsieur
le professeur who-really-dislikes-add-to-list don'tneed or even read those docs.

I am new enough to have many wholes in my Lisp knowledge so I need to look
up things, but not that new so I don't understand the docs, and when I red it
I had a laugh. What docs says to me in very complicated way is that my symbol
has to be a list. Conceptually speaking.

I don't feel that all those details about consing and the symbol itself being just
a symbol etc, are conceptually need to be conveyed att that stage.  add-to-list
is a higher level function, and I think that name itself is OK; I just think that we
are too considered here of the exact meaning of each and every thing. Maybe
we can re-formulate it to somehow focus more on the effect of the operation
and higher abstraction, then on low level detail of what are assembly parts and
how the operation itself is done? This is one of very used functions in init file and
one of probably first functions a new elisp programmer would look up. Can
we somehow put this knowledge further down into description, and choose more
descriptive name for the symbol? Even LIST-VAR is a step forward in this regard.
I think. And for your another mail, about putting add-to-list and push on same page,
I think you are probably correct.  I would personally perfer all list-modifying functions
in same place. Like a list AP.

I hope I don't sound obnoxious or am annoying.

Truly, thank you for the explanations.

Sorry for the format, I am not at home, thi is just from a browser from a work computer.
________________________________
Från: Robin Tarsiger <rtt@dasyatidae.com>
Skickat: den 4 december 2020 17:14
Till: Arthur Miller <arthur.miller@live.com>
Kopia: emacs-devel@gnu.org <emacs-devel@gnu.org>
Ämne: Re: Ad-hoc list structure tutorializing (was: Lispref add-to-list - doc is unnecessary convoluted)

Robin Tarsiger wrote:
> Arthur Miller wrote:
>> Maybe I don't understand lisp enough, but why is this not desirable:
>>
>> (add-to-list '(1 2 3) '4) or (add-to-list (list 1 2 3) 4)
>
> [...] For general list manipulation, the docstring
> explicitly calls out "please do not abuse it in Elisp code, where you
> are usually better off using ‘push’ or ‘cl-pushnew’".

To be abundantly clear on this, by the way, the non-mutating version
of that (without APPEND) is just the cons primitive itself:

  (cons 4 '(1 2 3))
  => (4 1 2 3)

and when APPEND is set, it's almost equivalent to, well, append:

  (append '(1 2 3) (list 4))
  => (1 2 3 4)

What those don't do is store the new list back where the old one
came from, which is where push and cl-pushnew come in for
local-variable/general-programming purposes and where add-to-list
comes in for config-variable-like purposes. The names are something
of a mishmash, admittedly, I imagine for historical reasons.

Note that you can try to "modify" the tail of a list with nconc:

  (let ((x '(1 2 3)))
    (nconc x (list 4)) ;; wrong! see below
    x)
  => (1 2 3 4)

... but you still need the store-back in general, because
the empty list has no cons cells to mutate!

  (let ((x '()))
    (nconc x (list 4)) ;; oops
    x)
  => nil

so that's only usable as an "optimization" in narrow cases where
you need fast append and can arrange the right guarantees about
the actual list structure, including that no other code is going
to be holding onto any of the sublists at the same time (else
they get a nasty surprise). Don't do that without a really good
reason.

(Aside: why not replace add-to-list with cl-pushnew always? Aside
from historical reasons and things like the buffer-local variable
idiom, being able to toggle APPEND is useful when list entries are
going to be processed in a specific order.)

-RTT

[-- Attachment #2: Type: text/html, Size: 14878 bytes --]

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

* Re: Ad-hoc list structure tutorializing
  2020-12-04 21:12           ` Christopher Dimech
@ 2020-12-05  7:45             ` Eli Zaretskii
  2020-12-06  5:45               ` Richard Stallman
  2020-12-06  5:39             ` Richard Stallman
  1 sibling, 1 reply; 23+ messages in thread
From: Eli Zaretskii @ 2020-12-05  7:45 UTC (permalink / raw)
  To: Christopher Dimech; +Cc: rtt, monnier, arthur.miller, emacs-devel

> From: Christopher Dimech <dimech@gmx.com>
> Date: Fri, 4 Dec 2020 22:12:52 +0100
> Cc: Arthur Miller <arthur.miller@live.com>, Robin Tarsiger <rtt@dasyatidae.com>,
>  emacs-devel@gnu.org
> 
> > Sent: Friday, December 04, 2020 at 9:24 PM
> > From: "Stefan Monnier" <monnier@iro.umontreal.ca>
> > To: "Robin Tarsiger" <rtt@dasyatidae.com>
> > Cc: "Arthur Miller" <arthur.miller@live.com>, emacs-devel@gnu.org
> > Subject: Re: Ad-hoc list structure tutorializing
> >
> > > (Aside: why not replace add-to-list with cl-pushnew always?
> >
> > Good question.
> >
> >
> >         Stefan "who really doesn't like `add-to-list`"
> >
> 
> Eli?

My vote is NO.



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

* Re: Ad-hoc list structure tutorializing
  2020-12-04 21:12           ` Christopher Dimech
  2020-12-05  7:45             ` Eli Zaretskii
@ 2020-12-06  5:39             ` Richard Stallman
  1 sibling, 0 replies; 23+ messages in thread
From: Richard Stallman @ 2020-12-06  5:39 UTC (permalink / raw)
  To: Christopher Dimech; +Cc: rtt, monnier, arthur.miller, emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

How about if we leave this part of Emacs alone and not spend time
discussing a tweak to it?

add-to-list is an old function which many users surely call.
The most important thing here is compatibility.
-- 
Dr Richard Stallman
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





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

* Re: Ad-hoc list structure tutorializing
  2020-12-05  7:45             ` Eli Zaretskii
@ 2020-12-06  5:45               ` Richard Stallman
  2020-12-06  5:57                 ` Robin Tarsiger
  0 siblings, 1 reply; 23+ messages in thread
From: Richard Stallman @ 2020-12-06  5:45 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: arthur.miller, dimech, monnier, rtt, emacs-devel

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

add-to-list is oriented at modifying a variable symbol which need not
be constant.  You can use it with a quoted symbol, of course.

cl-pushnew is oriented towards modifying a specific variable.
I don't know how one can do that with cl-pushnew.
Do you have to call symbol-value?  That is much less clean
than doing it with add-to-list.


-- 
Dr Richard Stallman
Chief GNUisance of the GNU Project (https://gnu.org)
Founder, Free Software Foundation (https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)





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

* Re: Ad-hoc list structure tutorializing
  2020-12-06  5:45               ` Richard Stallman
@ 2020-12-06  5:57                 ` Robin Tarsiger
  2020-12-06 14:01                   ` Arthur Miller
  0 siblings, 1 reply; 23+ messages in thread
From: Robin Tarsiger @ 2020-12-06  5:57 UTC (permalink / raw)
  To: emacs-devel

Richard Stallman wrote:
> add-to-list is oriented at modifying a variable symbol which need not> be constant.  You can use it with a quoted symbol, of course.
[etc.]

I will point out more concisely, in case my other message got
(perhaps rightfully) skipped, that I split off this subthread attempting
to better describe to Arthur why his new idea for the documentation
was poorly founded, and preempt certain other related ideas. My rhetorical
question, intended to help explain why add-to-list exists and is _not_
simply replaced with other list manipulation forms (in a way which I
imagined might confuse an elisp novice), was then quoted out of context
by itself to make it look like I was proposing to do that replacement.
(I believe this was accidental.) I was _not_ making such a proposal, and
I gave a longer list of potential reasons why not in the other message.

Since this has become more than cluttered enough already, this is the
last thing I will post on this topic unless personally asked.

-RTT



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

* Re: Ad-hoc list structure tutorializing
  2020-12-06  5:57                 ` Robin Tarsiger
@ 2020-12-06 14:01                   ` Arthur Miller
  0 siblings, 0 replies; 23+ messages in thread
From: Arthur Miller @ 2020-12-06 14:01 UTC (permalink / raw)
  To: Robin Tarsiger; +Cc: emacs-devel

Robin Tarsiger <rtt@dasyatidae.com> writes:

> Richard Stallman wrote:
>> add-to-list is oriented at modifying a variable symbol which need not> be constant.  You can use it with a quoted symbol, of course.
> [etc.]
>
> I will point out more concisely, in case my other message got
> (perhaps rightfully) skipped, that I split off this subthread attempting
> to better describe to Arthur why his new idea for the documentation
> was poorly founded, and preempt certain other related ideas. My rhetorical
> question, intended to help explain why add-to-list exists and is _not_
> simply replaced with other list manipulation forms (in a way which I
> imagined might confuse an elisp novice), was then quoted out of context
> by itself to make it look like I was proposing to do that replacement.
> (I believe this was accidental.) I was _not_ making such a proposal, and
> I gave a longer list of potential reasons why not in the other message.
>
> Since this has become more than cluttered enough already, this is the
> last thing I will post on this topic unless personally asked.
>
> -RTT
Seems like some of my mails never got to the list; I don't see them
myself, but I see them in my out folder. No idea why.

@RTT Anyway, thank you for the explanations, you made it clear why it was
designed the way it was. For what it does, I would illustrate it with a
**List in C, a pointer to a pointer but there are no pointers and
references in Lisp, just symbols and values so it takes a symbol and can
not take a value. What we wish is a pointer to a list. I am not sure but
I think that at least LIST-VAR is better than just SYMBOL, maybe
LIST-SYMBOL; whatever.

@RMS Yes it is old function, but for some peopel it is new. I was just
reading documentation of it and thought it was neither very clear nor
well written: "better be a list" or "quote if if you wish" does not
sound to me as a clear explanation of precondition. Since people have
complained that documentation is incomprehensive, so I just tried to
make it a bit easier to diggest while I was anyway reading it. Didn't
know it would release a storm of comments and proposal for replacement.

Best regards
/a




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

end of thread, other threads:[~2020-12-06 14:01 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-04  2:17 Lispref add-to-list - doc is unnecessary convoluted Arthur Miller
2020-12-04  2:27 ` Christopher Dimech
2020-12-04  2:36 ` Robin Tarsiger
2020-12-04  3:29   ` Arthur Miller
2020-12-04  3:35   ` Arthur Miller
2020-12-04  8:35     ` Lars Ingebrigtsen
2020-12-04  8:29 ` Eli Zaretskii
2020-12-04 15:28   ` Arthur Miller
2020-12-04 15:56     ` Robin Tarsiger
2020-12-04 16:14       ` Ad-hoc list structure tutorializing (was: Lispref add-to-list - doc is unnecessary convoluted) Robin Tarsiger
2020-12-04 20:24         ` Ad-hoc list structure tutorializing Stefan Monnier
2020-12-04 21:12           ` Christopher Dimech
2020-12-05  7:45             ` Eli Zaretskii
2020-12-06  5:45               ` Richard Stallman
2020-12-06  5:57                 ` Robin Tarsiger
2020-12-06 14:01                   ` Arthur Miller
2020-12-06  5:39             ` Richard Stallman
2020-12-04 21:40           ` add-to-list vs cl-pushnew Robin Tarsiger
2020-12-04 21:51             ` Robin Tarsiger
2020-12-04 22:47         ` Sv: Ad-hoc list structure tutorializing (was: Lispref add-to-list - doc is unnecessary convoluted) arthur miller
2020-12-04 17:03     ` Lispref add-to-list - doc is unnecessary convoluted Drew Adams
2020-12-04 17:24       ` arthur miller
2020-12-04 18:02         ` Drew Adams

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).