First of all, let me say I'm a beginner in Lisp. To be honest I have been a beginner for some time now, but there are still many things I don't know well.
While I was writing this question, I came up with a strange bug in my code.
Here is a function that will return the list (0 1 ... n)
with the list e
appended. It uses rplacd
along the way to keep track of the last element, to avoid a final call to last
.
For example, (foo 4 '(x))
returns (0 1 2 3 4 x)
.
The "head" is stored in a
, which is not simply nil
, because there is only one nil
, and never a copy of it (if I understand correctly), hence I can't simply append to nil
.
(defun foo (n e)
(let* ((a (list nil)) (tail a))
(loop for i to n
do (rplacd tail (setf tail (list i)))
finally (rplacd tail (setf tail e))
(return (cdr a)))))
(defun bar (n e)
(let* ((a '(nil)) (tail a))
(loop for i to n
do (rplacd tail (setf tail (list i)))
finally (rplacd tail (setf tail e))
(return (cdr a)))))
The only difference between these functions is the (list nil)
replaced by '(nil)
in bar
. While foo
works as expected, bar
always returns nil
.
My initial guess is this happens because the original cdr
of a
is indeed nil
, and the quoted list may be considered constant. However, if I do (setf x '(nil)) (rplacd x 1)
I get (nil . 1)
as expected, so I must be at least partially wrong.
bar
's parentheses are unbalanced. – Splenic'(nil)
. Sorry for this. – Spouse'
is supposed to be treated as immutable. Does that hold in Common Lisp? It looks like you're trying to mutate the thing. – Splenicnil
in it, and in the other version,nil
is evaluated to an empty list. EDIT: No, it looks like the symbolnil
evaluates to the symbolnil
. – Splenic(list nil)
and'(nil)
represent almost the same thing. For example, they areequal
, but noteq
(which means they are not the same object, though they have the same "structural" contents, see here). Andnil
is a weird object, that represents both the false boolean and the empty list, and two variables set tonil
are alwayseq
(the same object), and this causes some problems when you want to initialize a list to something empty, to later update. – Spouse