Barry Margolin
7/18/2015 3:55:00 PM
In article <f98a0774-0340-4d61-b88d-9ae8e233a31b@googlegroups.com>,
Andrei Zorine <zoav1602@gmail.com> wrote:
> Dear group!
>
> Could somebody please explain this strange behavior of _nreverse_ to me? I
> define a function like this:
> (defun f () (let ((aa)) (setq aa '((something))) (push 'else aa) (nreverse
> aa)))
>
> The two successive calls for (f) produce different results:
> * (f)
>
> ((SOMETHING) ELSE)
> * (f)
>
> (ELSE (SOMETHING) ELSE)
> *
>
> (This is SBCL 1.2.8) I don't understant the variable capture - when (f) is
> called for the second time, the setq on aa assins ((SOMETHING) ELSE) instead
> of just ((SOMETHING)) to it. If I replace a call to nreverse with a call
> reverse then the two invocations of (f) produce the same expected output.
>
> A.Z.
NREVERSE is a destructive function, and '((something)) creates a
constant list. The consequences are undefined if you try to modify a
constant.
What actually happens is that this modifies the literal list that's in
the function definition, so you're redefining the function.
Change your code to:
(defun f ()
(let ((aa))
(setq aa (list '(something)))
(push 'else aa)
(nreverse aa)))
Now it creates a fresh list every time you call it, and you won't see
this anomaly.
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***