emacs-devel
[Top][All Lists]
Advanced

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

Re: Ad-hoc list structure tutorializing (was: Lispref add-to-list - doc


From: Robin Tarsiger
Subject: Re: Ad-hoc list structure tutorializing (was: Lispref add-to-list - doc is unnecessary convoluted)
Date: Fri, 4 Dec 2020 10:14:45 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.12.0

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



reply via email to

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