2

I want to make each mu4e-*-folder a lambda function which takes msg as a function, while folder is set to produce this lambda function.

(defun my-get-eval-func (folder)
  (lambda (msg)
    (my-mu4e-get-folder folder msg)))

(dolist (folder (list
                  'mu4e-sent-folder
                  'mu4e-drafts-folder
                  'mu4e-trash-folder
                  'mu4e-refile-folder))
  (set folder (my-get-eval-func folder)))

The code above seems not working. Why and what's the correct way to do?

xuhdev
  • 8,018
  • 2
  • 41
  • 69
  • 1
    possible duplicate of [What is the difference between Lisp-1 and Lisp-2?](http://stackoverflow.com/questions/4578574/what-is-the-difference-between-lisp-1-and-lisp-2) – sds Dec 19 '14 at 11:13
  • @sds Probably "dynamic-by-default is different from lexical-by-default". – Vatine Dec 20 '14 at 21:02

2 Answers2

3

By default, Emacs Lisp is dynamically scoped, so closures don't work:

(defun adder (x) #'(lambda (y) (+ x y)))
(funcall (adder 3) 4)

yields the error "void variable x", as the call to the lambda expression is trying to access x in the current dynamic environment. You can either tell Emacs to use lexical binding (Section 11.9.3 of the Emacs Lisp manual), or inline the value of x manually:

(defun adder (x) `(lambda (y) (+ ',x y)))

In your case, this means doing something like:

(defun my-get-eval-func (folder)
  `(lambda (msg)
     (my-mu4e-get-folder ',folder msg)))

Note further that Emacs Lisp is a Lisp-2, meaning that each symbol has two bindings ­— the value binding and the function binding. You didn't specify which binding you want to set, but if it is the function binding, you will need to replace set with fset in your code (see Section 12.8 of the Emacs Lisp manual).

jch
  • 5,382
  • 22
  • 41
0

I think you want fset instead of of set.

sds
  • 58,617
  • 29
  • 161
  • 278
  • I think the issue is about expecting closures in a dynamically scoped Lisp, not about the function cell. – jch Dec 20 '14 at 20:02