[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: newbie elisp question (nreverse or reverse)

From: Pascal Bourguignon
Subject: Re: newbie elisp question (nreverse or reverse)
Date: Mon, 21 May 2007 23:39:23 +0200
User-agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/22.0.99 (gnu/linux)

Seweryn Kokot <address@hidden> writes:

> Hello,
> Does it really matter if I use nreverse or reverse in the following
> example?
> (setq bla '("a" "b"))
> (setq bla (append bla '("c")))
> (setq bla (reverse bla))
> or
> (setq bla (nreverse bla))


(defun f ()
  (let ((blah '(a b)))
     (setf blah (append blah '(c))) ; here no problem, blah is copied, 
                                    ; but not '(c)!  
     (setf blah (nreverse blah))    ; ERROR! '(c) is modified!

(list (f) (f)) --> ((c b a) (a b c b a))  ; !!!!

(progn (pprint (symbol-function 'f)) (terpri) nil)
(lambda ()
  (let ((blah '(a b)))
    (setf blah (append blah '(c b a)))  ; The program has been modified!!!
    (setf blah (nreverse blah))
--> nil

So, never use destructive functions on structures that are not
mutable: make a copy first, or build mutable structures from the
start, or just use the non-destructive functions, which makes the copy

(defun f ()
  (let ((blah '(a b)))
     (setf blah (append blah (copy-list '(c))))
     (setf blah (nreverse blah))  ; ok, because blah is a freshly consed list.

(defun f ()
  (let ((blah '(a b)))
     (setf blah (append blah '(c)))
     (setf blah (reverse blah))  ; always ok.

Of course, if the tail comes from an argument, you cannot use
nreverse, since you never know whether the client will call you with
'(c) or with (list 'c), then always use reverse in this case:

(defun f (c)
  (let ((blah '(a b)))
     (setf blah (append blah c))
     (setf blah (reverse blah))  ; always ok.

__Pascal Bourguignon__           

NOTE: The most fundamental particles in this product are held
together by a "gluing" force about which little is currently known
and whose adhesive power can therefore not be permanently

reply via email to

[Prev in Thread] Current Thread [Next in Thread]