如何在elisp中的表达式中传递运算符?

时间:2016-05-23 04:04:35

标签: emacs elisp

我正在阅读 Lisp的根,并且遇到了这个例子:

(
 (lambda (f) (f '(b c)))
 '(lambda (x) (cons 'a x)))

但是,如果我在Emacs进行评估,我就得到了

Symbol's function definition is void: f

如果我在https://repl.it/languages/scheme上尝试使用Schema作为lisp解释器,我得到了

Error: ('lambda ('x) ('cons ('quote 'a) 'x)) is not a function [(anon), (anon)]

如果删除第二个lambda表达式上的quote,此示例适用于repl.it,但仍然在Emacs上出现相同的错误。

1 个答案:

答案 0 :(得分:4)

f功能应用于'(b c)必须使用funcall完成。以下是有效的:

(
 (lambda (f) (funcall f '(b c)))
 '(lambda (x) (cons 'a x)))

并评估为(a b c)

保罗·格雷厄姆可能在他的article中使用了一些lisp变体,只有一个命名空间用于函数名和数据变量( Lisp-1 或Scheme模型),而Elisp是 Lisp-2 语言,具有不同的函数/变量名称空间。这允许函数和变量具有相同的名称。

所以像

这样的东西
(some-function some arguments)

elisp执行程序仅搜索函数名称空间中的some-function,当您想要从变量名称空间调用与变量关联的函数时,它会使funcallapply这样的构造成为必需。

如果不理解,elisp中的单独函数/变量名称空间可能会导致意外行为:

(defun do-something () (1))
(setq do-something #'(lambda () (2)))

(do-something) ;; => 1
(funcall do-something) ;; => 2