Elisp中的高阶函数

Mir*_*lov 9 emacs elisp dynamic-binding higher-order-functions

我创建了一个在Elisp中返回函数的函数:

(defun singleton-set (elem)
  (defun f (n) (= n elem))
  f)
Run Code Online (Sandbox Code Playgroud)

我尝试在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)
Run Code Online (Sandbox Code Playgroud)

由于Lisp-1和Lisp-2有什么区别?我将代码更改为

(defun singleton-set (elem)
  (defun f (n) (= n elem))
  #'f)
Run Code Online (Sandbox Code Playgroud)

并调用(funcall (singleton-set 5) 5),但现在错误是

*** Eval error *** Symbol's value as variable is void: elem

我从elisp了解到:从内部函数捕获变量,这是由于Emacs Lisp的动态绑定.

如何在Emacs Lisp中使函数返回函数?这种机制与Python,Scala或Clojure等其他语言有什么不同?

相关问题:

Gar*_*ees 10

来自NEWS于Emacs 24:

Lisp在Emacs 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)
Run Code Online (Sandbox Code Playgroud)


geo*_*car 5

如何在Emacs Lisp中使函数返回函数成为可能?

使用假的闭包,和lexical-let

这种机制与其他语言(例如Python,Scala或Clojure)不同的原因是什么?

理查德·斯托曼(Richard Stallman )在不久前写的一篇论文中回答了这个问题