[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.lisp

nreverse and side-effects

zoav1602

7/18/2015 8:43:00 AM

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.
2 Answers

Sebastian Christ

7/18/2015 9:39:00 AM

0


Someone with more knowledge should correct me, but anyway:

The problem isn't nreverse here. The problem is that you push onto a
quoted list. And the quoted list is static data. Try this:

(defun f () (let ((aa)) (setq aa (list '(something))) (push 'else aa) (nreverse aa)))

The result is always the same: ((something) else)

This fact is someway shadowed by using reverse, because reverse creates
a new list you. Implicitly.

Hope this help. But beware. I'm not overqualified to teach such things.

Best,
Sebastian

Barry Margolin

7/18/2015 3:55:00 PM

0

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 ***