title: Emacs: the code in the body of a defun or defmacro cannot refer to surrounding lexical variables?
body: <p><strong>Update 2013 May</strong>: As of GNU Emacs 24.3.1, (let .. (defun..)) bytecompiles just fine without warning and the bytecompiled code works the same as not-compiled code. Just don't forget to add the file variable <code>lexical-binding: t</code> to the file to be bytecompiled. Workarounds at the end of this question is now not necessary.</p>
  
  <hr>
  
  <p><a href="http://www.gnu.org/software/emacs/manual/html_node/elisp/Lexical-Binding.html" rel="nofollow">Lexical Binding - Emacs Lisp Manual</a> has this paragraph:</p>
  
  <blockquote>
    <p>Note that functions like symbol-value, boundp, and set only retrieve or modify a variable's dynamic binding (i.e. the contents of its symbol's value cell). Also, the code in the body of a defun or defmacro cannot refer to surrounding lexical variables.</p>
  </blockquote>
  
  <p>I am not sure if I am getting the meaning of the second sentence right. In the following code which should be run in lexical binding mode, the code in the body of a defun is successfully referring to the lexical binding value of the name <code>n</code>.</p>
  
  <pre><code>(let ((n 0))
    (defun my-counter ()
      (incf n)))
  
  (my-counter) ;; 1
  (my-counter) ;; 2
  </code></pre>
  
  <p>Is the sentence simply saying that (let .. (defun ..)) is a bad practice?</p>
  
  <hr>
  
  <p><strong>Workarounds</strong>:</p>
  
  <pre><code>;; -*- lexical-binding: t -*-
  
  ;; a way to define the counter function without byte-compile error or warning
  
  (defvar my--counter-func
    (let ((n 0))
      (lambda ()
        (setq n (1+ n)))))
  
  (defun my-counter ()
    (funcall my--counter-func))
  
  ;; another way to define the counter function, again without byte-compile error or warning
  
  (fset 'my-another-counter
        (let ((n 0))
          (lambda ()
            (setq n (1+ n)))))
  </code></pre>
  
  <p>And here's the code for testing the above code:</p>
  
  <pre><code>;; run:
  ;; emacs -q --load path-to-the-el-file-of-this-code.el
  
  (load "path-to-file-defining-my-counter.elc") ;; loading the ELC file to test if byte-compiled code runs as expected.
  
  (print (my-counter)) ;; 1
  (print (my-counter)) ;; 2
  
  (print (my-another-counter)) ;; 1
  (print (my-another-counter)) ;; 2
  </code></pre>