【问题标题】:Why does the following elisp code not working?为什么以下 elisp 代码不起作用?
【发布时间】:2014-12-21 06:15:46
【问题描述】:

我想让每个mu4e-*-folder 成为一个将msg 作为函数的lambda 函数,而folder 被设置为生成这个lambda 函数。

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

上面的代码似乎不起作用。为什么以及正确的做法是什么?

【问题讨论】:

标签: elisp


【解决方案1】:

默认情况下,Emacs Lisp 是动态作用域的,所以闭包不起作用:

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

产生错误“void variable 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 节)。

【讨论】:

    【解决方案2】:

    我认为你想要fset 而不是set

    【讨论】:

    • 我认为问题在于期望动态范围的 Lisp 中的闭包,而不是函数单元格。
    猜你喜欢
    • 1970-01-01
    • 2016-11-12
    • 2021-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    • 2017-06-15
    • 1970-01-01
    相关资源
    最近更新 更多