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

How to pass operators in expressions in elisp?

我正在阅读 Root of 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 上仍然出现相同的错误。

将函数 f 应用到 '(b c) 必须使用 funcall 来完成。所以以下工作:

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

并计算为 (a b c)

Paul Graham 可能在他的 article 中使用了一些 lisp 的变体,其中只有一个命名空间用于函数名称和数据变量(Lisp-1 或 Scheme 模型),而Elisp 是一种 Lisp-2 语言,具有针对 functions/variables 的不同命名空间。这允许函数和变量具有相同的名称。

所以对于像

这样的事情
(some-function some arguments)

elisp 执行器仅在函数命名空间中搜索 some-function,这使得当您想从变量中调用与变量关联的函数时需要像 funcallapply 这样的构造命名空间。

如果不理解 elisp 中单独的 function/variable 命名空间,可能会导致意外行为:

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

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