我创建了一个在 Elisp 中返回函数的函数:
(defun singleton-set (elem)
(defun f (n) (= n elem))
f)
我尝试在 IELM 中运行它,但它失败了:
ELISP> (singleton-set 5)
*** Eval error *** Symbol's value as variable is void: f
ELISP> ((singleton-set 5) 5)
*** Eval error *** Invalid function: (singleton-set 5)
由于 Lisp-1 和 Lisp-2 有什么区别? 我将代码更改为
(defun singleton-set (elem)
(defun f (n) (= n elem))
#'f)
并调用(funcall (singleton-set 5) 5)
,但现在错误是
*** Eval error *** Symbol's value as variable is void: elem
我从elisp:从内部函数捕获变量了解到,这是由于Emacs Lisp的动态绑定。
如何使函数返回函数在 Emacs Lisp 中成为可能?这种机制与Python,Scala或Clojure等其他语言不同的原因是什么?
相关问题:
- ELISP 函数作为参数和返回值
- Elisp 交互函数名称
- 如何在 Emacs Lisp 中创建临时函数
- 在 elisp 中,如何将函数放入变量中?
来自 Emacs 24 的NEWS
:
Emacs 24.1 中的 Lisp 变化
- 代码现在可以默认使用词法范围,而不是动态范围。
lexical-binding
变量启用局部词法范围 变量。 它通常通过第一个文件局部变量设置 行,在这种情况下,它适用于该文件中的所有代码 文件。
所以,在 Emacs 24 中:
(setq lexical-binding t)
(defun singleton-set (elem) (lambda (n) (= n elem)))
(mapcar (singleton-set 1) '(0 1 2 3))
===> (nil t nil nil)
如何使函数返回函数在 Emacs Lisp 中成为可能?
使用假封口,lexical-let
.
这种机制与Python,Scala或Clojure等其他语言不同的原因是什么?
理查德·斯托曼(Richard Stallman)在他不久前写的一篇论文中回答了这个问题。
(defun singleton-set (elem)
`(lambda (n) (= n ,elem))
参见:elisp 函数作为参数和返回值