11

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 ?

Sake
  • 4,033
  • 6
  • 33
  • 37
  • You might save yourself a lot of time by using a Common Lisp with Slime in emacs. SBCL is my favourite. – justinhj Aug 05 '11 at 16:54
  • @justinhj: Thanks for the tip. However, I'm learning lisp just to get to know emacs better. Unless something is going to change my mind, I think I prefer python over lisp with a really wide margin. – Sake Aug 06 '11 at 05:46
  • That makes sense. BTW when using emacs lisp to extend emacs think about how you would do the same in Python. IMHO emacs lisp is an ideal language for extending a text editor, whilst Python, which I also really like, has many different uses. – justinhj Aug 06 '11 at 05:58
  • Emacs lisp does not really reflect the experience of using lisps targeted at "real programming" like common lisp. Accordingly, it's not a fair comparison with python, which is not really intended to be used as an embedded scripting language as its first use. – Marcin Dec 12 '11 at 12:38
  • Marcin, I'm sure lisp is a really powerful concept. Unfortunately, even after few months, I personally still not very comfortable with lisp syntax. – Sake Dec 12 '11 at 12:43

4 Answers4

18

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.

danlei
  • 14,121
  • 5
  • 58
  • 82
12

Emacs24 from bzr now supports lexical binding out of the box; it just isn't activated by default since there are many packages which still deliberately or inadvertently depend on dynamical scoping. Your above code should work just fine in Emacs24 in a buffer where the variable 'lexical-binding' is set to 't'.

pokita
  • 1,241
  • 10
  • 12
  • 1
    Thanks for the info. I'm really curious if painless transition from dynamic-binding to lexical-binding could be possible. But it's great to know that emacs is still evolving. And I'm really looking forward to devote some effort to help when my skill is good enough. – Sake Aug 06 '11 at 05:41
  • Dynamic binding is one of the key reasons that Emacs is so easily extensible. It's certainly nice to have the alternative available, but I hope that dynamic binding will always be the standard for most elisp code. – phils Aug 07 '11 at 12:10
2

See this page: http://www.emacswiki.org/emacs/FakeClosures

Drew
  • 29,895
  • 7
  • 74
  • 104
1

another solution using Emacs' unintern symbol:

ELISP> (setf power-of-two
         (let ((p (make-symbol "previous-power-of-two")))
           (set p 1) (list 'lambda '()
           (list 'setf p
             (list '* p 2)))))

ELISP> (funcall power-of-two)
2
ELISP> (funcall power-of-two)
4
ELISP> (funcall power-of-two)
8
Sake
  • 4,033
  • 6
  • 33
  • 37