From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: pjb@informatimago.com (Pascal J. Bourguignon) Newsgroups: gmane.emacs.help Subject: Re: when should a variable to quoted? Date: Sat, 13 Sep 2008 11:38:18 +0200 Organization: Informatimago Message-ID: <87k5dg9yid.fsf@hubble.informatimago.com> References: <5bdb1b73-bf04-49a3-8629-61d32ef6f899@p31g2000prf.googlegroups.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1221299097 6354 80.91.229.12 (13 Sep 2008 09:44:57 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 13 Sep 2008 09:44:57 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Sat Sep 13 11:45:52 2008 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1KeRhO-0006bh-7L for geh-help-gnu-emacs@m.gmane.org; Sat, 13 Sep 2008 11:45:50 +0200 Original-Received: from localhost ([127.0.0.1]:40373 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KeRgN-0002PC-PD for geh-help-gnu-emacs@m.gmane.org; Sat, 13 Sep 2008 05:44:47 -0400 Original-Path: news.stanford.edu!headwall.stanford.edu!newshub.sdsu.edu!exabot.com!proxad.net!feeder1-2.proxad.net!cleanfeed3-b.proxad.net!nnrp12-1.free.fr!not-for-mail Original-Newsgroups: gnu.emacs.help Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAQMAAABtzGvEAAAABlBMVEUAAAD///+l2Z/dAAAA oElEQVR4nK3OsRHCMAwF0O8YQufUNIQRGIAja9CxSA55AxZgFO4coMgYrEDDQZWPIlNAjwq9 033pbOBPtbXuB6PKNBn5gZkhGa86Z4x2wE67O+06WxGD/HCOGR0deY3f9Ijwwt7rNGNf6Oac l/GuZTF1wFGKiYYHKSFAkjIo1b6sCYS1sVmFhhhahKQssRjRT90ITWUk6vvK3RsPGs+M1RuR mV+hO/VvFAAAAABJRU5ErkJggg== X-Accept-Language: fr, es, en X-Disabled: X-No-Archive: no User-Agent: Gnus/5.1008 (Gnus v5.10.8) Emacs/22.2 (gnu/linux) Cancel-Lock: sha1:+jB9QjB97QanbgEpKM3QQkt8D+o= Original-Lines: 96 Original-NNTP-Posting-Date: 13 Sep 2008 11:38:18 MEST Original-NNTP-Posting-Host: 88.182.134.169 Original-X-Trace: 1221298698 news-1.free.fr 7210 88.182.134.169:60886 Original-X-Complaints-To: abuse@proxad.net Original-Xref: news.stanford.edu gnu.emacs.help:162178 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:57521 Archived-At: sunway writes: > (add-to-list 'll "a") > (delete-dups ll) > > The variable "ll" needs be quoted in add-to-list, while not quoted in > delete-dups, why? any special reasons? Lisp passes its arguments by-value. Therefore a function cannot modify the variables from which the values it gets come. It still can modify the value, when it is mutable, but not the variable. Usually, when we want to have a variable (or in general, a place) modified, we have to use a macro, or a special operator. (setq ll (list 1 2 3)) ; setq is a special operator. (require 'cl) (push 0 ll) ; push is a macro Otherwise, you must take care to get the result and store it back into the variable: (setq ll (delete ll 2)) ; delete modifies the value of ll, and returns ; the modified value, but when it's the first ; element that is deleted, we need to modify ; the variable too. For some reason (probably historical), emacs lisp authors prefer to use a function add-to-list instead of a macro push. Because there is no lexical variable in emacs lisp, but only special variables, where the value of the variable is always stored inside the symbol, in the symbol-value slot, we can consider any symbol to be a "pointer" to the variable. Therefore it is possible to pass a symbol to a function that will modify its symbol-value, thus modifying the variable named by this symbol. In lisp with lexical variables such as scheme or Common Lisp, it wouldn't work. In the case of delete-dups, it's like in the case of delete, but since it can never reduce to an empty list if passed an non empty list, it can modify the value in such a way that the variable always points to the right value. Namely, delete-dups modifies the first cons cell of the list it gets. Delete doesn't take this special step, so when you delete the first elements, the result returned and the value of the variable are not the same cons cell: (let ((list (list 1 1 2 2 3 3))) (print (delete 1 list)) list) prints: (2 2 3 3) returns: (1 1 2 2 3 3) We could try to write delete so it modifies the first cons cell: (defun smart-delete (item list) (let* ((first-cell list) (head (cons nil list)) (list head)) (while (cdr list) (if (equal item (cadr list)) (setf (cdr list) (cddr list)) (setf list (cdr list)))) (if (null (cdr head)) nil (progn (setf (car first-cell) (cadr head) (cdr first-cell) (cddr head)) first-cell)))) (let ((list (list 1 1 2 2 1 3 3))) (print (smart-delete 1 list)) list) prints: (2 2 3 3) returns: (2 2 3 3) But this wouldn't work when emptying the list: (let ((list (list 1 1 1))) (print (smart-delete 1 list)) list) prints: nil returns: (1 1 1) because there is no way of modifying a cons cell to make it the symbol nil. -- __Pascal Bourguignon__ http://www.informatimago.com/ ATTENTION: Despite any other listing of product contents found herein, the consumer is advised that, in actuality, this product consists of 99.9999999999% empty space.