2014-12-19 79 views
2

我想讓每個mu4e-*-folder都是一個lambda函數,它需要msg作爲函數,而folder被設置爲產生這個lambda函數。爲什麼下面的elisp代碼不工作?

(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))) 

上面的代碼似乎不工作。爲什麼和什麼是正確的方法?

+1

[Lisp-1和Lisp-2有什麼區別?](http://stackoverflow.com/questions/4578574/what-is-the-difference-between-lisp-1-and- lisp-2) – sds 2014-12-19 11:13:13

+0

@sds可能是「動態默認與默認詞法不同」。 – Vatine 2014-12-20 21:02:07

回答

3

默認的Emacs Lisp是動態範圍的,所以關閉不起作用:

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

產生錯誤「無效變量x」,因爲在調用lambda表達式試圖訪問x在目前的動態環境。您可以告訴Emacs的使用詞法綁定(中的Emacs Lisp手冊第11.9.3),或手動內聯的x值:

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

在你的情況,這意味着做這樣的事情:

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

請注意,Emacs Lisp是一個Lisp-2,這意味着每個符號都有兩個綁定 - 值綁定和函數綁定。您沒有指定要設置的綁定,但如果它是功能綁定,則需要在代碼中將set替換爲fset(請參閱Emacs Lisp手冊的第12.8節)。

0

我想你想要fset而不是set

+0

我認爲這個問題是關於期待動態範圍的Lisp中的閉包,而不是關於函數單元。 – jch 2014-12-20 20:02:52