From: "Pascal J. Bourguignon" <pjb@informatimago.com>
To: help-gnu-emacs@gnu.org
Subject: Re: Why doesn't nconc change my variable?
Date: Sun, 05 Oct 2014 20:04:49 +0200 [thread overview]
Message-ID: <87k34emlz2.fsf@kuiper.lan.informatimago.com> (raw)
In-Reply-To: mailman.10460.1412473030.1147.help-gnu-emacs@gnu.org
Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:
> Hi list,
>
> I don't get it.
>
> (setq my-list ())
> (nconc my-list '("wtf"))
>
> and my-list is still nil.
>
> If, OTOH, I do
>
> (setq my-list ())
> (setq my-list (nconc my-list '("wtf")))
Also, you are doing something dangerous here:
You are mixing mutable and immutable data.
This is dangerous, because now you may believe that your variable
contains mutable data, and try to mutate it, and you will actually try
to mutate immutable data, (which has usually strange or catastrophic
results).
(defvar my-list)
(setq my-list (list 1 2 3))
;; now, my-list contains mutable data. You can modify the car or
;; the cdr of any cell in the list.
(setq my-list (nconc my-list '("wtf")))
;; Now, my-list is bound to the list: (1 2 3 "wtf")
;; but this list is made of 3 mutable cons cells, and one immutable
;; cons cell, with one immutable string!
If you were to perform any of:
(setq my-list (nconc my-list '("bad")))
(setq my-list (car (last my-list) "bad"))
(setq (aref (car (last my-list)) 0) ?W)
(setq my-list (delete* "wtf" my-list :test (function string=)))
;; etc.
you would get strange/catastrophical results:
For example, try:
(defun strange (list)
(nconc list '("wtf")))
(let ((a (strange (list 1 2 3))))
(setf (car (last a)) "BAD")
(list a (strange (list 4 5 6))))
--> ((1 2 3 "BAD") (4 5 6 "BAD")) ; WTF, where is "wtf"?
If you try with:
(setf print-circle t)
(let ((a (strange (list 1 2 3))))
(setf (car (last a)) "strange")
(list a (strange (list 4 5 6))))
--> ((1 2 3 . #1=("strange")) (4 5 6 . #1#))
this may give you a hint of what's happening.
So avoid mixing mutable and immutable data, or consider the result to be
immutable (and therefore avoid using destructive operations on it).
Notice that append, while it copies the N-1 first arguments, it keeps
the last argument, so (append list '("wtf")) is no better
than (nconc list '("wtf")).
You need (nconc list (list 'wtf)) ; if you want immutable elements
or (nconc list (list (format "%s" "wtf"))) ; if you want
; mutable elements.
--
__Pascal Bourguignon__ http://www.informatimago.com/
“The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.” -- Carl Bass CEO Autodesk
next prev parent reply other threads:[~2014-10-05 18:04 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <mailman.10460.1412473030.1147.help-gnu-emacs@gnu.org>
2014-10-05 1:59 ` Why doesn't nconc change my variable? Pascal J. Bourguignon
2014-10-05 9:35 ` Marcin Borkowski
[not found] ` <mailman.10474.1412501757.1147.help-gnu-emacs@gnu.org>
2014-10-05 17:50 ` Pascal J. Bourguignon
2014-10-05 18:04 ` Pascal J. Bourguignon [this message]
2014-10-05 1:36 Marcin Borkowski
2014-10-05 1:58 ` Drew Adams
2014-10-05 9:54 ` Marcin Borkowski
2014-10-05 10:52 ` Thorsten Jolitz
2014-10-05 16:29 ` Drew Adams
2014-10-05 16:38 ` Drew Adams
[not found] ` <mailman.10475.1412502895.1147.help-gnu-emacs@gnu.org>
2014-10-05 18:12 ` Pascal J. Bourguignon
2014-10-05 18:14 ` Pascal J. Bourguignon
2014-10-05 18:31 ` Pascal J. Bourguignon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87k34emlz2.fsf@kuiper.lan.informatimago.com \
--to=pjb@informatimago.com \
--cc=help-gnu-emacs@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.