Discussion of Common Lisp
-
BIOS
- Posts: 15
- Joined: Sun Apr 04, 2010 1:55 pm
Post
by BIOS » Fri Jan 14, 2011 10:58 am
Can anyone tell me what I'm doing wrong here:
Code: Select all
(let* ((x '(1 2 3 4 5))
(y))
(setf y (nreverse x)))
I just want to set one variable as the reverse list of the other but i get the following error:
; in: LAMBDA NIL
; (NREVERSE X)
;
; caught WARNING:
; Destructive function NREVERSE called on constant data.

-
vanekl
- Posts: 12
- Joined: Wed Dec 15, 2010 10:25 am
Post
by vanekl » Fri Jan 14, 2011 11:08 am
Some versions of lisp don't allow you to destructively modify what it considers constant data when you use a quote.
Try this instead:
Code: Select all
(let ((x (list 1 2 3 4 5))
y)
(setf y (nreverse x))
(values y x))
-
BIOS
- Posts: 15
- Joined: Sun Apr 04, 2010 1:55 pm
Post
by BIOS » Fri Jan 14, 2011 11:41 am
Hey thanks for the reply. Yep your code works fine. As does this i found out:
Code: Select all
(let* ((x '(1 2 3 4 5))
(y))
(setf y (reverse x)))
Which indicates the issue lies with the nreverse function?
-
vanekl
- Posts: 12
- Joined: Wed Dec 15, 2010 10:25 am
Post
by vanekl » Fri Jan 14, 2011 11:56 am
It's a combination of quote and nreverse. Nreverse tries to destructively change x in some versions of lisp, but it cannot because the quote makes x constant. On the other hand, 'reverse' makes a copy of x and doesn't try to change x, so no error.
-
BIOS
- Posts: 15
- Joined: Sun Apr 04, 2010 1:55 pm
Post
by BIOS » Fri Jan 14, 2011 12:13 pm
Sweet. Thanks for the clarification!

-
JamesF
- Posts: 98
- Joined: Thu Jul 10, 2008 7:14 pm
Post
by JamesF » Sun Jan 16, 2011 3:59 pm
BIOS wrote:Can anyone tell me what I'm doing wrong here:
Code: Select all
(let* ((x '(1 2 3 4 5))
(y))
(setf y (nreverse x)))
This smells like C-style thinking. Why not this?
Code: Select all
(let* ((x '(1 2 3 4 5))
(y (reverse x)))
You'd actually need
let* in this case, whereas
let is sufficient in your original snippet, where it doesn't matter which order the bindings for
x and
y are evaluated.
-
Jasper
- Posts: 209
- Joined: Fri Oct 10, 2008 8:22 am
- Location: Eindhoven, The Netherlands
-
Contact:
Post
by Jasper » Tue Jan 18, 2011 2:17 pm
Afaik QUOTE does
not make x constant, quote make the variable x point to a list '(1 2 3 4 5), but that list is *not* created when you call it, it is always there. So if you do:
Code: Select all
(defun quote-abuse ()
(let ((list '(1 2 3 4 5)))
list))
(setf (car (quote-abuse)) 'unexpected)
(quote-abuse) ;=> (unexpected 2 3 4 5)
I guess the effect is that one
should treat it as a constant,(which why it warns) but it isn't really.
-
nuntius
- Posts: 538
- Joined: Sat Aug 09, 2008 10:44 am
- Location: Newton, MA
Post
by nuntius » Tue Jan 18, 2011 7:22 pm
For some odd reason, I love comparing CL to C.
In C, the expression char *x="some string"; doesn't inherently mean that "some string" is a constant. However, there are efficiency gains from making it so; and string literals are now constant by mandate/standardization. (Modifying a string literal invokes "undefined behavior" -- meaning don't do that. Some compilers put them in read-only memory; thus a write will cause a memory fault.)
Same thing goes for quoted list literals in CL.