复习 Lisp: Syntax and Semantics

Emacs 里面 lambda 是个宏,展开来是 #'(lambda ...),后者就是对 funtion 这个 special form 的调用。你说的没错。

对于 CL 来说,你说错了:不是列表,是闭包。CL 为了提高效率是尽量避免在 run time 用列表这种原始而低效的数据结构的。闭包在 CL 里面是一种特殊的数据结构,是不能被当作列表操作。

但是你这句话对于动态作用域的 Lisp,比如 NewLisp,没有开 lexical 绑定的 Emacs Lisp 是正确的。在这些解释性语言中,lambda 本质的确就是列表。下面这段 Emacs Lisp 代码可以证明。

(setq foo (lambda () 1))

foo ;; => (lambda nil 1)

(car foo) ;; => lambda

甚至对于开了 lexical binding 的 Emacs Lisp,你说 lambda 本质是列表也是基本正确的:

(setq lexical-binding t)

(lambda () 1) ;; => (closure (t) nil 1)

(car (lambda nil 1)) ;; => closure

;; 最有趣的要来了

(fset 'bar '(clozure (t) nil 1))

(bar) ;; => 1

;; 还不够刺激?

(funcall '(closure (t) nil 1)) ;; => 1

((closure (t) (x) x) 2) ;; => 2

从这里我们看到了 Common Lisp 和 Emacs Lisp 一个重要的区别就是,很多在 Common Lisp 中打印成不可读入的数据结构,在 Emacs Lisp 中是用可重新读入的方法表示的。

见我翻译的:

所以我加了引号。

2 个赞