在elisp的高阶功能(Higher-order functions in Elisp)

2019-08-01 05:25发布

我创建了一个在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,斯卡拉或Clojure的其他语言不同的原因是什么?

相关的问题:

  • elisp的函数作为参数并作为返回值
  • elisp的交互功能名称
  • 如何创建的Emacs Lisp临时函数
  • 在elisp的,我怎么把一个函数的变量?

Answer 1:

NEWS的Emacs的24:

在Emacs Lisp的24.1变化

  • 代码现在可以通过默认,而不是动态作用域使用词汇范围。 该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)


Answer 2:

如何使功能恢复中的Emacs Lisp可能的功能?

使用假瓶盖和lexical-let

这是什么机制,是从像Python,斯卡拉或Clojure的其他语言不同的原因是什么?

理查德·斯托曼回答了这个问题在文中写道前一阵子。



Answer 3:

(defun singleton-set (elem)
  `(lambda (n) (= n ,elem))

请参阅: elisp的功能参数和返回值



文章来源: Higher-order functions in Elisp