emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Lispref add-to-list - doc is unnecessary convoluted


From: Robin Tarsiger
Subject: Re: Lispref add-to-list - doc is unnecessary convoluted
Date: Fri, 4 Dec 2020 09:56:21 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.12.0

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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]