Elisp中的高阶函数

时间:2012-10-07 20:16:56

标签: emacs elisp higher-order-functions dynamic-binding

我创建了一个在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)

由于What is the difference between Lisp-1 and 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: capturing variable from inner function了解到这是由于Emacs Lisp的动态绑定。

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

相关问题:

3 个答案:

答案 0 :(得分:10)

来自Emacs 24的NEWS

  

Lisma在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)

答案 1 :(得分:5)

  

如何在Emacs Lisp中使函数返回函数?

使用fake closureslexical-let

  

这种机制与Python,Scala或Clojure等其他语言有什么不同?

Richard Stallman answered this question在他不久前写的一篇论文中。

答案 2 :(得分:3)

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

请参阅:elisp functions as parameters and as return value