From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Pascal J. Bourguignon" Newsgroups: gmane.emacs.help Subject: Re: add-to-list with lexical variables Date: Sat, 08 Jun 2013 19:08:09 +0200 Organization: Informatimago Message-ID: <8738ssledi.fsf@kuiper.lan.informatimago.com> References: <87txl8u68b.fsf@gmail.com> <87r4gcln2h.fsf@kuiper.lan.informatimago.com> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Trace: ger.gmane.org 1370711862 20273 80.91.229.3 (8 Jun 2013 17:17:42 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 8 Jun 2013 17:17:42 +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 Jun 08 19:17:40 2013 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 1UlMln-0002eE-1Q for geh-help-gnu-emacs@m.gmane.org; Sat, 08 Jun 2013 19:17:39 +0200 Original-Received: from localhost ([::1]:33205 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UlMlm-0005AP-K8 for geh-help-gnu-emacs@m.gmane.org; Sat, 08 Jun 2013 13:17:38 -0400 Original-Path: usenet.stanford.edu!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail Original-Newsgroups: gnu.emacs.help Original-Lines: 111 Original-X-Trace: individual.net BRCOCac3OqI65BVgHWM4agJIJDMhOqh0YBftuKWbTqVN3VXaQq Cancel-Lock: sha1:YWI5ODU3OWIzYjBlN2NhZmFiYTVkODExMDk0ZGEwMjY4NzQ4MmZhZA== sha1:AVJBEqsv9H+i1ChDb5Fbn5vUOr4= Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAQMAAABtzGvEAAAABlBMVEUAAAD///+l2Z/dAAAA oElEQVR4nK3OsRHCMAwF0O8YQufUNIQRGIAja9CxSA55AxZgFO4coMgYrEDDQZWPIlNAjwq9 033pbOBPtbXuB6PKNBn5gZkhGa86Z4x2wE67O+06WxGD/HCOGR0deY3f9Ijwwt7rNGNf6Oac l/GuZTF1wFGKiYYHKSFAkjIo1b6sCYS1sVmFhhhahKQssRjRT90ITWUk6vvK3RsPGs+M1RuR mV+hO/VvFAAAAABJRU5ErkJggg== X-Accept-Language: fr, es, en User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) Original-Xref: usenet.stanford.edu gnu.emacs.help:199133 X-Mailman-Approved-At: Sat, 08 Jun 2013 13:17:30 -0400 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:91400 Archived-At: Hongxu Chen writes: > However I still don't know the difference `lexical-binding' and > `lexical-let' brings. Are there some authoritative introductions/tutorials? http://www.emacswiki.org/emacs/DynamicBindingVsLexicalBinding Also, any Common Lisp tutorial covers them. You may be interested by my explanations in the context of Common Lisp: https://groups.google.com/group/comp.lang.lisp/msg/58f1c7ed53d0c0d6 But basically, it's a question of time vs. space. Dynamic is change over time. So dynamic binding will be concerned by the time, by WHEN things are bound and referenced. Lexical is textual. So lexical binding will be concerned by space, by WHERE in the text things are bound and referenced. With dynamic binding, things occur at certain times: #+BEGIN_SRC elisp ;; with lexical-binding set to nil: (let ((list (list 1 2 3))) (add-to-list 'list 0)) #+END_SRC time ---- 1. the function list is called with arguments 1 2 and 3. 2. it returns a list: (1 2 3). 3. let creates a variable, it saves any dynamic binding the symbol list may have, and it names the variable with the symbol list, and it binds it (dynamically, at this time 3.) to the list (1 2 3). 4. (quote list) is evaluated. 5. it returns the symbol list. 6. 0 is evaluated. 7. it returns 0 8. the function add-to-list is called with as arguments, the symbol list and the integer 0. 9. the function changes the dynamic binding of the symbol list. remember at this time, while the function add-to-list is being called, there symbol list is dynamically bound to the list (1 2 3), since the time 3. 10. it returns, and the dynamic binding to the variable list has been changed. 11. let destroys the dynamic binding of list, and destroys the variable named list. Whatever dynamic binding list had before is restored. With lexical binding, what matters is the space, the place where expressions are: #+BEGIN_SRC elisp ;; with lexical-binding set to t: (let ((list (list 1 2 3))) (add-to-list 'list 0)) #+END_SRC (let ((list (list 1 2 3))) ;; From HERE (add-to-list 'list 0) ;; To HERE, there is a lexical variable named list. ) (defun add-to-list (variable value) ;; From HERE … … code of add-to-list … ;; To HERE, we're outside the lexical scope of the let form above. ;; There is no lexical variable named list here! Only the variables ;; and parameters of add-to-list. ) So there's no way for add-to-list to access directly the lexical variable list defined in the let form. It could access it indirectly, if you passed it a closure. See for example: http://www.informatimago.com/articles/usenet.html#C-like-pointers-in-Lisp (those CL examples should run the same in emacs lisp with lexical-binding set to t). But since add-to-list is predefined not to use a closure, but to modify a dynamic binding, it won't change a lexical binding. It's not it's purpose, it's not what it's designed to do. -- __Pascal Bourguignon__ http://www.informatimago.com/ A bad day in () is better than a good day in {}. You can take the lisper out of the lisp job, but you can't take the lisp out of the lisper (; -- antifuchs