From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Drew Adams" Newsgroups: gmane.emacs.bugs Subject: bug#12314: 24.2.50; `add-to-history': use `setq' with `delete' Date: Sat, 8 Sep 2012 15:26:04 -0700 Message-ID: <852E534DA6A342708069D17B8C3C3DFF@us.oracle.com> References: <7602D24B74DE42CF9901322634B85CA2@us.oracle.com> <87sjas4mc2.fsf@gnu.org> <83ipbomv6e.fsf@gnu.org> <2C45207ADF0E46BC98AF1B486695F632@us.oracle.com> <83fw6smti6.fsf@gnu.org> <9A8F619FD7584123A6319BD089E444E4@us.oracle.com> <83bohgmrdv.fsf@gnu.org> <83a9x0mq5e.fsf@gnu.org> <8E40573C868D4B339513A16A02588F5E@us.oracle.com> <837gs4mcqy.fsf@gnu.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Trace: ger.gmane.org 1347143202 17270 80.91.229.3 (8 Sep 2012 22:26:42 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 8 Sep 2012 22:26:42 +0000 (UTC) Cc: 12314@debbugs.gnu.org, cyd@gnu.org To: "'Eli Zaretskii'" Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sun Sep 09 00:26:44 2012 Return-path: Envelope-to: geb-bug-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 1TATUC-0001DH-43 for geb-bug-gnu-emacs@m.gmane.org; Sun, 09 Sep 2012 00:26:44 +0200 Original-Received: from localhost ([::1]:48976 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TATU8-0004Rz-S4 for geb-bug-gnu-emacs@m.gmane.org; Sat, 08 Sep 2012 18:26:40 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:37577) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TATU6-0004Ru-IB for bug-gnu-emacs@gnu.org; Sat, 08 Sep 2012 18:26:39 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TATU5-0007sm-9p for bug-gnu-emacs@gnu.org; Sat, 08 Sep 2012 18:26:38 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:39635) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TATU5-0007sg-64 for bug-gnu-emacs@gnu.org; Sat, 08 Sep 2012 18:26:37 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.72) (envelope-from ) id 1TATUU-0006lS-0L for bug-gnu-emacs@gnu.org; Sat, 08 Sep 2012 18:27:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: "Drew Adams" Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 08 Sep 2012 22:27:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 12314 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 12314-submit@debbugs.gnu.org id=B12314.134714320725982 (code B ref 12314); Sat, 08 Sep 2012 22:27:01 +0000 Original-Received: (at 12314) by debbugs.gnu.org; 8 Sep 2012 22:26:47 +0000 Original-Received: from localhost ([127.0.0.1]:49181 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1TATUE-0006l0-DK for submit@debbugs.gnu.org; Sat, 08 Sep 2012 18:26:46 -0400 Original-Received: from acsinet15.oracle.com ([141.146.126.227]:41753) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1TATUB-0006ks-Fi for 12314@debbugs.gnu.org; Sat, 08 Sep 2012 18:26:45 -0400 Original-Received: from ucsinet22.oracle.com (ucsinet22.oracle.com [156.151.31.94]) by acsinet15.oracle.com (Sentrion-MTA-4.2.2/Sentrion-MTA-4.2.2) with ESMTP id q88MQEUk006677 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sat, 8 Sep 2012 22:26:15 GMT Original-Received: from acsmt358.oracle.com (acsmt358.oracle.com [141.146.40.158]) by ucsinet22.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id q88MQDGF028579 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sat, 8 Sep 2012 22:26:14 GMT Original-Received: from abhmt115.oracle.com (abhmt115.oracle.com [141.146.116.67]) by acsmt358.oracle.com (8.12.11.20060308/8.12.11) with ESMTP id q88MQDhk009745; Sat, 8 Sep 2012 17:26:13 -0500 Original-Received: from dradamslap1 (/71.202.147.44) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sat, 08 Sep 2012 15:26:13 -0700 X-Mailer: Microsoft Office Outlook 11 In-Reply-To: <837gs4mcqy.fsf@gnu.org> X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.6157 Thread-Index: Ac2OCAGFmJjsg5VbSAycEKdxis9qxwAAgMBQ X-Source-IP: ucsinet22.oracle.com [156.151.31.94] X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:63981 Archived-At: > > > Why is it even necessary to talk about destructive > > > modifications, if we are to advise to assign the result anyway? > > > > Not sure I understand the question. It is because these > > operations can be destructive of list structure that we advise that. > > If you need to forget about the old value and assign the new one > returned by 'delete', why does it matter that the modification was > destructive? That pertains to the old value that you need to toss > anyway. Perhaps we are miscommunicating. That general advice about assigning the variable is only a general guideline; it is not absolute. You will NOT always want to assign the variable to the return value. It all depends on what you want/need. The doc about these operations needs to describe what they do, and what they do is typically destructive; that is, they typically modify list structure. The bit about variables here is only a heads-up about a classic gotcha, nothing more. It is because we often have variables that are assigned/bound to the list structure that we might be modifying that we should BE AWARE that these operations do NOT do ANYTHING wrt variables. All they do is modify list structure. We typically give them access to the list structure via the values of variables. But the operations have nothing to do with the variables themselves - they are completely unaware of the existence of any variables. Hence, IF you want your variable, and not just some particular list structure, to always be updated to reflect your modification, then that is a separate step that you must perform after modification: assign the variable to the resulting list structure that you want. This is not so obvious to newbies, just as fiddling with pointers is not obvious to a newbie to a language that has pointers. A function such as `add-to-history' or `add-to-list' is something quite different. Those functions act on a VARIABLE, whose value is a list. IOW, they are aware of the existence of a certain variable - they are passed the SYMBOL as argument, not just its value, and they make sure that the variable gets updated. The modification functions that operate only on lists have no awareness of any variables. They are not passed a variable as argument. Their job is simply to return a list value, possibly (typically) modifying existing list structure in the process. > > If you have variables that point to some list structure > > that you modify somehow, then it is up to you to ensure that > > the variables point to what you want them to point to after > > such modification. > > Variables that point to that list structure will point to something > whose value is unpredictable, a.k.a. "garbage". It is enough to say > that the old value is garbage and shouldn't be used, IMO. No. It all depends. Lisp programs that use list modification do so sometimes for performance in calculating the new list, but more often they do so in order to take advantage of SHARING list structure. (This too is something not so obvious to newbies - they can get the impression that these operations are mainly about saving cycles in calculating the return value.) For such programs - which are IMO the typical and the strongest (most important) uses of list modification, what you call garbage is anything but. Consider the example I gave before: (setq a '(1 2 3 4)) (setq b (cddr a)) a => (1 2 3 4) b => (3 4) (delq 4 b) a => (1 2 3) b => (3) The fact that modifying the list pointed to by `b' also modifies the list pointed to by `a' is an advantage for certain kinds of programs. Without a separate `setq' operation, the variables point to the same cons cells they pointed to at the outset. And in some cases that is exactly what you want: you want to remove the last link in the list that is shared by `a' and `b'. List structure can be shared among multiple variables, so that changes to the structure are seen by more than one - perhaps all. Each variable provides a different view of parts or all of the list structure. > > It all depends on what you want/need. > > You can never want/need the old value, because you cannot predict what > it will be. Not so. If you know `a' and `b' before the operation then you know them afterward as well. What `a' and `b' here do NOT care about is `4' or the cons that contains `4' in its car. To THEM it is now garbage - it is no longer part of the lists THEY point to. But some other variable, `c', might well care about (point to) that particular cons. E.g., (setq a '(1 2 3 4)) (setq b (cddr a)) (setq c (cdr b)) Here, `c' points to the last cons cell in `a' and `b'. After the `delq' operation, that cons cell is no longer part of the lists pointed to by `a' and `b'. But it is still pointed to by `c'. And in such programs it can also be the case that what is garbage to `a' and `b' now will later be important to them. IOW, these 3 lists/views might well be logically related and dynamically change in related ways. Removing the sublist `c' from `a' and `b' might be a temporary operation - that sublist might be added back later. And when it is added back it might no longer contain `4' - it might then be (42 19 "hike"). You get the point. It is probably easier to see all of this by looking at `setcar' and `setcdr'. For `delq' we do not necessarily want/need to expose exactly how the implementation works, other than to say what it does in general and point out that it might NOT modify any existing list structure in some cases. But for `setcar' and `setcdr' the behavior is transparent and simple. They always modify list structure, and in simple ways. Think of variables whose values are cons cells as pointers. List modification can move such pointers around. In the above case, the pointer from the cdr of the first cons of `b' to its second cons is changed to point to nil. That's all. And `b' is a sublist of `a', so now `a's value reflects the structure change also. That can be a very handy thing. Certain kinds of programs take advantage of this sharing. Others - most - do not.