help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: add-to-list with lexical variables


From: Pascal J. Bourguignon
Subject: Re: add-to-list with lexical variables
Date: Sat, 08 Jun 2013 19:08:09 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux)

Hongxu Chen <leftcopy.chx@gmail.com> 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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]