Elisp 中的高阶函数



我创建了一个在 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 函数作为参数和返回值

相关内容

  • 没有找到相关文章

最新更新