For some existing explanations on this, see:
(let ((x '(a)))
(nconc x '(b c))
Don't do this.
nconc works by destructively modifying all but its last argument, but
x in this case is a quoted list literal, which is not safe to modify; see
(info "(elisp) Mutability").
It is okay to use
nconc if you know for sure that
x is safe to modify, as in the following example:
(let ((x (list 'a)))
(nconc x '(b c))
If you are not sure whether
x is safe to modify, use
append instead, or make a copy of
x first, e.g. using
Is someone able to explain the last exemple? I would have expect it to return
(b c). Did I miss something?
nconc does is link all of its arguments together, by modifying each argument (except the last) in-place to point to the next argument.
How would this work for a
nil argument? The answer is it doesn't: appending an empty list to any other list is the same as not appending the empty list at all!
(nconc (list 1) () (list 2)) is equivalent to
(nconc (list 1) (list 2)), which is
(1 2) - the empty list is skipped.
Besides, even if it did make sense to link
nil like any other list, then Emacs would complain, because
nil is a protected constant that can't be modified.
However, the following is working
Yes, that is the correct way to use
nconc if you don't know ahead of time whether
x will be empty. If
x is guaranteed to be non-
nil, then using
nconc without assigning the result back to same variable is fine. If, OTOH,
x might be
nil, then you must assign the result back to some variable, otherwise the result will be lost.
but in that case I don’t see added value compared to
append makes a copy of all but its last argument. It can also concatenate sequences of other types, like strings and vectors, in addition to lists.
nconc is intended for a very specific purpose: linking mutable lists in-place and fast, without any extra memory allocations due to copying. It is effectively a generalisation of
setcdr that operates on the last link of any number of cons cells.
If you're not sure which of the two to use, it's safer to go with