理解Emacs Lisp里的quote(')

Emacs Lisp里的quote是个让人糊涂的东西 从开始接触Emacs Lisp我对它的理解就很模糊 但随着折腾Emacs的时间变长 对它的理解也深刻了 加上看了Emacs Lisp的官方入门资料 对quote算是理解了 今天看到有新人不懂 所以写一写

首先 quote的用法是(quote x) 表示对x这个符号quote 但更常见的写法是'a 这是quote的「语法糖」 二者实际是等价的

之后我们用例子来讲解 首先打开Emacs的*scratch* 之后的操作都在里面进行

定义一个变量a 在一行的最后按C-j 表示eval这个语句并且输出(每一行注释里写了输出的内容):

1
(setq a 1) ; => 1

然后我们看看对a'a进行eval的结果:

1
2
a ; => 1
'a ; => a

这就是quote的用处了 如果不加 则eval的结果是对这个变量取值 而加了会将它本身返回

单独看这个功能可能没有什么 如果把这个和Emacs Lisp的执行方式放到一块就会发现它的用处了

对于Emacs的lisp解释器来说 形如(x y z)语句是一个函数调用 函数名是x 参数是yz Emacs会对这些参数进行取值然后调用相应的函数 所以执行下面两个语句:

1
2
(1 2 3) ; 报错:Invalid function: 1
'(1 2 3) ; => (1 2 3)

第一个会报错 因为Emacs认为它是一个调用1这个函数的语句 而我们没有定义1这个函数 所以出错了 第二个就返回了(1 2 3)这个list

其实Emacs执行Lisp代码和你在*scratch*里eval语句是一样的 所以对于你感兴趣的东西你可以自己在里面尝试 比如你会发现 一些常量 比如1"abc" 加不加quote是一样的 而有些东西 比如变量 加不加是不同的

借这个机会我们再稍微探索一下setq 其实setq也是个语法糖 它表示“set quote” 也就是说(setq a 1)就是(set 'a 1) 或者如果你不嫌麻烦(set (quote a) 1) 为啥这里要加quote呢 我们来试试 如果不加会怎么样

1
(set a 1) ; 报错:Wrong type argument: symbolp, 1

如果你看懂了上面的分析你就明白了 这里Emacs尝试对a这个变量取值 结果是数值1 而这个语句尝试将1赋值给1 当然会出错 所以set后一定要跟quote 因为用的太频繁了 所幸搞一个独立的函数 也就是setq