The Emacs lisp manual states about the function nconc that:
Since the last argument of nconc is not itself modified, it is reasonable to use a constant list, such as '(4 5), as in the above example. For the same reason, the last argument need not be a list
And indeed I can write
(setq x '(1 2 3))
=> (1 2 3)
(nconc x 0)
=> (1 2 3 . 0)
but that yields a totally broken list:
(length x)
=> eval: Wrong type argument: listp, 0
(butlast x)
=> butlast: Wrong type argument: listp, 0
(reverse (cdr (reverse '(1 2 3 . 0))))
doesn't cut it either.minibuffer.el
use it, in particular completion-all-completions
and the like.They're not "broken" lists; they're actually known as improper lists (as opposed to nil
-terminated lists, which are proper lists). Many list functions, such as length
and butlast
that you just named, expect proper lists, and listp
returns true only for proper lists.
Improper lists are used in association lists (where the associations are often not proper; though the alist itself must be proper).
If you want to make an improper list proper, you have two options:
Here's a procedure I wrote called properise
which will do the former:
(defun properise (x)
(let ((r nil))
(while (consp x)
(push (pop x) r))
(nreverse r)))
(If you want the latter behaviour, add (unless (null x) (push x r))
just before the nreverse
line.)