Search code examples
emacslispelispcommon-lispdynamic-scope

How to overcome the lack of local variable for emacs lisp closure


I'm now studying Emacs Lisp from the reference manual and Common Lisp from a LISP Book.

from the Common Lisp book

>> (setf power-of-two
     (let ((previous-power-of-two 1))
       #'(lambda ()
           (setf previous-power-of-two
             (* previous-power-of-two 2)))))

>> (funcall power-of-two)
2

>> (funcall power-of-two)
4

>> (funcall power-of-two)
8

The function won't work in Emacs Lisp because of its dynamic binding behavior.

I wonder if it is possible to implement the same function in Emacs Lisp without introducing a global variable ?


Solution

  • Update:

    By now, Emacs 24 has been officially released, and it supports lexical binding without using lexical-let, when the buffer-local variable lexical-binding is non-nil. See also M-: (info "(elisp) using lexical binding") and pokita's answer.


    You can use lexical-let from the Common Lisp Extensions (the "CL package"):

    elisp> (require 'cl)
    cl
    elisp> (setf power-of-two
                 (lexical-let ((previous-power-of-two 1))
                   #'(lambda ()
                       (setf previous-power-of-two
                             (* previous-power-of-two 2)))))
    (lambda
      (&rest --cl-rest--)
      (apply
       (lambda
         (G175638)
         (set G175638
              (*
               (symbol-value G175638)
               2)))
       '--previous-power-of-two-- --cl-rest--))
    
    elisp> (funcall power-of-two)
    2
    elisp> (funcall power-of-two)
    4
    elisp> (funcall power-of-two)
    8
    

    I've also heard about a lexbind branch of GNU Emacs.