Update to 2013 . Starting with GNU Emacs 24.3.1, (let .. (defun ..)) bytecompiles is just fine, without warning, and the code encoded in the code works the same as the non-compiled code. Just remember to add the lexical-binding: t file variable to the file to be copied. Workarounds at the end of this question are no longer needed.
Lexical Binding - Emacs Lisp Guide contains this paragraph:
Note that functions such as symbol-value, boundp, and set only retrieve or modify the dynamic binding variable (i.e., the contents of the symbol value cell). In addition, code in the body of defun or defmacro cannot reference surrounding lexical variables.
I am not sure if I understood the meaning of the second sentence correctly. In the following code, which should be run in lexical binding mode, the code in the defun body successfully refers to the lexical binding value of the name n .
(let ((n 0)) (defun my-counter () (incf n))) (my-counter) ;; 1 (my-counter) ;; 2
This sentence just says that (let .. (defun ..)) is bad practice?
Bypass
;; -*- 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)))))
And here is the code to test the above 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
source share