From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Drew Adams Newsgroups: gmane.emacs.help Subject: RE: Why doesn't nconc change my variable? Date: Sun, 5 Oct 2014 09:29:12 -0700 (PDT) Message-ID: <6e14f951-570b-4445-a682-d48c18c31221@default> References: <87y4svl2ku.fsf@wmi.amu.edu.pl> <3867d7c2-936d-4441-91d6-3b12dc959391@default> <87vbnylu3z.fsf@wmi.amu.edu.pl> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable X-Trace: ger.gmane.org 1412526600 1053 80.91.229.3 (5 Oct 2014 16:30:00 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 5 Oct 2014 16:30:00 +0000 (UTC) To: Marcin Borkowski , help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Sun Oct 05 18:29:52 2014 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Xaogy-0005cr-2u for geh-help-gnu-emacs@m.gmane.org; Sun, 05 Oct 2014 18:29:52 +0200 Original-Received: from localhost ([::1]:47994 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Xaogx-0006UT-H9 for geh-help-gnu-emacs@m.gmane.org; Sun, 05 Oct 2014 12:29:51 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:51432) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Xaoge-0006TK-Cd for help-gnu-emacs@gnu.org; Sun, 05 Oct 2014 12:29:41 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XaogV-0006Ou-Io for help-gnu-emacs@gnu.org; Sun, 05 Oct 2014 12:29:32 -0400 Original-Received: from userp1040.oracle.com ([156.151.31.81]:29177) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XaogV-0006Ne-Aq for help-gnu-emacs@gnu.org; Sun, 05 Oct 2014 12:29:23 -0400 Original-Received: from ucsinet22.oracle.com (ucsinet22.oracle.com [156.151.31.94]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id s95GTHFK014745 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sun, 5 Oct 2014 16:29:18 GMT Original-Received: from aserz7022.oracle.com (aserz7022.oracle.com [141.146.126.231]) by ucsinet22.oracle.com (8.14.5+Sun/8.14.5) with ESMTP id s95GTFfS002439 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sun, 5 Oct 2014 16:29:17 GMT Original-Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by aserz7022.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id s95GTE92004603; Sun, 5 Oct 2014 16:29:14 GMT In-Reply-To: <87vbnylu3z.fsf@wmi.amu.edu.pl> X-Priority: 3 X-Mailer: Oracle Beehive Extensions for Outlook 2.0.1.8.2 (807160) [OL 12.0.6691.5000 (x86)] X-Source-IP: ucsinet22.oracle.com [156.151.31.94] X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 156.151.31.81 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:100286 Archived-At: > Do I get it correctly that the "destructiveness" of some > functions (like nconc) does /not/ mean that they /change/ some of > their arguments, but only that they /may/ do it, and that relying > on that is risky? Yes. That's exactly what it means. "Destructive" operations are _potentially_ destructive of existing data. That label is just shorthand, to contrast with nondestructive operations that do not modify data. It's about functions that you use for their side effects and not just their values. > What is the "canonical" way to append an element to a list, in > the sense that I have a variable containing (=3Dpointing to?) a > list, I want it to point to a list one element longer? There is no "canonical" way. Use `append' if you want to return a new list that is a copy (but not a deep copy) of the original list but with an additional element at the end. Use `nconc' if you want to obtain a list that has the additional element at the end, and you don't care about preserving the original list as it was. The list you obtain _might or might not_ share some structure with the argument lists. A good guideline is to _not_ use "destructive" operations, in general. When there are use cases where you really might be able to take advantage of them _you will know it_. Another way to put this is that you need to really understand and be comfortable with side effects before you try to make real use of them. Most of the time you can (and should) avoid them (at least those that modify list structure etc.) - and not have to worry about them. If you do want to start experimenting with list-structure modification then another guideline is to use "destructive" operations only on a new list (new cons cell) that you have assigned to only one variable. IOW, create a new list and play with that. And do not assign any variables to any parts of that list structure. Do not use destructive operations on an existing list from someone else's code, or even from your code, if you are not sure what you are doing. Later, you might relax that second guideline: part of the point of using list-modification operations is to _share_ list structure (have different variables point, directly or indirectly) to the same cons cell. But this is not something to be trifled with. It is not easy to follow or debug program logic when it starts fiddling with list structure and dependent structures. Anyway, what you are not quite understanding so far, I think, (but you seem to be getting closer), is just what a Lisp _variable_ is, including how it relates to its value. 1. A variable is a Lisp _symbol_ that is associated with a value at a given moment. 2. That value could be a cons (so that the value is a non-empty list or a dotted list). 3. A cons that might be the value of a variable has an *independent* existence from the variable's symbol. The symbol is mapped to its value. Function `symbol-value' returns the value. a. It is possible to change the value of the variable (i.e., change the association, so that the `symbol-value' of the symbol points to something different. b. It is also possible to not change that association (mapping, binding) between symbol and cons-cell value, but to change the car or cdr of the cons cell itself. This has the indirect effect of changing the value: the thing that is the value changes, instead of the variable binding changing. 4. If something changes the car or cdr of the cons cell value of a variable, this changes the variable value. It still points to the same cons cell, but the content of that cell is not the same as it was. 5. A "destructive" "function" such as `nconc' _might or might not_ change a cons in one of its arguments. Typically, the function is used for its side effects. But typically also, the _result_ returned by the function is the cons that is the main side-effect goal. For `nconc', for example, the return value is the list resulting from the append/concatenate operation. That returned list (for `nconc') might or might not share structure with one of the arguments. 6. Regardless of whether a given destructive function does in fact change a cons in one of its arguments, it does _not_ fiddle with the mapping between any symbols and any conses. IOW, it does not reassign or rebind any variables. Typically, the function _sees no variables_ at all. It receives only cons (or nil) _values_ as its arguments. It has no way of knowing (and it does not care) about some variable that you might have assigned or bound to one of the conses that it looks at and might modify. That variable is your affair - your responsibility, not the function's. 7. (Again) If you have a variable that has a value that is a cons, and if that cons is modified, then the variable still points to it, i.e., it points to the updated value. Modifying that cons has the indirect side effect of modifying the variable value. 8. If you have a variable that has a value that is a cons, and if you call a function that does _not_ modify that cons (i.e., no modification of any part of it - e.g., any part of a cons chain reached from its car or its cdr), then the variable value is _not_ changed. 9. #8 includes the case where you call a "destructive" function that might change something else (e.g. another cons cell, not reached from the cons pointed to by the variable). The variable value is _not_ changed. 10. #9 is relevant even if the function _returns_ a different cons, which represents the intended _result_ of the operation. The variable does _not_ point to this other cons. If the cons pointed to by the variable is not, itself, changed, then the variable value is not changed (by the operation). The variable still points to the same cons - nothing about the function changes what the variable points to. 11. So yes, if the _result_ returned by the operation is what you want the variable value to be (and it typically is), then it is up to you to reassign the variable value to it. IOW, use `setq' to update the variable to have the new value. HTH. Others will no doubt state all or most of this more briefly, e.g. using some simple code examples to make it clear. The description above is intentionally somewhat repetitive. If it helps, fine. If not, sorry.