emacs-devel
[Top][All Lists]
Advanced

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

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


From: arthur miller
Subject: Sv: Ad-hoc list structure tutorializing (was: Lispref add-to-list - doc is unnecessary convoluted)
Date: Fri, 4 Dec 2020 22:47:47 +0000

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

reply via email to

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