前一篇《 勤劳,仍是懒惰?》讲述了编程的目的在于让本身或者别人更省力地完成一些重复性的劳动。从这篇文章开始,正式学习 Emacs Lisp 编程方面的知识。
到如今为止,咱们已经大体见识了在 Emacs Lisp 语言中如何定义一个函数,也见识了interactive
、insert
、read-string
、list
等函数的基本用法。我几乎未对这些函数给出细致的解释,可是经过几回简单的实践,它们的功能应该是显而易见的。不过,这种显而易见是创建在对编程的基本知识有所了解的基础之上的。编程
以segmentfault
(list (read-string "变量名称?") (read-string "类型?") (read-string "数量?"))
为例,这个表达式是什么意思呢?函数
假若将 (read-string "变量名称?")
、(read-string "类型?")
、(read-string "数量?")
分别视为 x
、y
、z
,那么上述代码可简化为:学习
(list x y z)
这行代码揭示的是,list
是一个函数,它接受三个参数。事实上,它能够接受无限多个参数,只要计算机的内存空间足够。code
list
函数的做用是让它的全部参数排队,从左向右,先来后到,造成一个序列。这种序列称为列表。list
函数的参数可分为两类,一类是原子,另外一类是列表。内存
不只 list
函数能如此,全部函数皆能如此。get
咱们现今探索到的世界真相,有一条最基本的原理:物质由原子构成。化学家相信,化学反应中的最小单位是原子。数学
对于一个程序而言,它的输入数据与输出数据,以及程序自己,这一切也皆由原子构成。string
以上文里的 list
函数所接受的参数 x
为例,当这个参数的值为 (read-string "变量名称?")
时,要想从这种表象中看到原子,须要不断剥离或穿透由表达式构成的外衣。it
(read-string "变量名称?")
是一个表达式,在 Emacs Lisp 解释器看来,它是一个函数求值表达式,亦即 read-string
是一个函数,如今它接受了一个参数 "变量名称?"
。如今,你已经看到了一个原子,就是这个参数。这个原子,名叫字串。
read-string
函数在接受这个参数以后,会将它显示于 Emacs 的微缓冲区,而后它等待接收着咱们在微缓冲区里的输入。当我输入 foo <RET>
的时候,Emacs 会将我输入的 foo
变成字串原子传给 read-string
,而 read-string
会将这个原子做为它的求值结果。
所以,Emacs Lisp 解释器对 (read-string "变量名称?")
的求值,最终获得的是一个字串。
字串只是 Emacs Lisp 语言里的一种原子。不要小看它,古今中外,任何一部文学著做皆由这种原子构成。在 Emacs 的缓冲区,它的本体也不过是一个字串。
除了字串以外,Emacs Lisp 还提供了符号、数字、布尔值(真值 t
与假值 nil
)、向量这些原子。有关它们的一些概念与用法,在编程的过程当中遇到它们时再做介绍。由于这部分知识单独拿出来,逐一细说,不只无趣,并且无趣。
在化学家看来,分子由原子构成。在 Emacs Lisp 中,列表也由原子构成。所以,不妨将列表当成一种分子。虽然之前咱们没有学过编程,可是却学过一点点化学知识。
列表是一种很重要的分子。由于列表不只可由原子构成,也能够由列表构成,还能够由原子与列表混合构成。由列表或者由原子与列表混合构成的列表,它们能够构成各类各样的分子,例如环状的、树状的、表格状的、图状的……不妨将列表称为元分子。
(list x y z)
能够构成列表 (x y z)
,亦即 Emacs Lisp 解释器对这个表达式的求值结果是 (x y z)
。能够经过一个小试验证明这一点。
用 Emacs 打开 init.el 文件,而后在文件末尾增长一行代码:
(list "foo" "double" "n")
而后,将光标移动到这行代码的尾部,而后向 Emacs 发送指令 C-x C-e
,而后 Emacs Lisp 解释器便会对这行代码(表达式)求值,求值结果显现于微缓冲区,即:
("foo" "double" "n")
这是一个由三个字串原子构成的列表。
注:光标,就是在 Emacs 窗口中某处一闪一闪的矩形块,表示在这个位置上能够插入文本。
如今,再在 init.el 文件的末尾增长一行代码:
(list "foo" "double" "n" (list "foo" "double" "n"))
再用 C-x C-e
对这行代码求值,结果为:
("foo" "double" "n" ("foo" "double" "n"))
这个结果依然是一个列表,但它是由三个字串原子与一个列表构成。
如今,咱们知道了表达式 (list "foo" "double" "n")
的求值结果是列表 ("foo" "double" "n")
,可是认真看一下这个表达式与它的求值结果,能够发现它们的形状同样。Emacs Lisp 解释器如何区分一个可求值的表达式与一个列表呢?
(list "foo" "double" "n")
其实也是一个列表,只不过它与 ("foo" "double" "n")
的不一样之处在于它的第一个元素(不是化学里的元素,而是数学集合论中的元素,将列表视为集合),不是字串,不是数字,不是布尔值,也不是向量,它是一个符号,与 +
、-
、*
、/
这些数学运算符号没有本质上的区别。
例如,要计算 1 + 2,用 Emacs Lisp 语言,可将其描述为:
(+ 1 2)
这里的 +
是符号,1
与 2
是数字原子,这三者构成了一个列表,但 Emacs Lisp 解释器会认为这是个函数求值表达式。没错,在 Emacs Lisp 中,+
也是一个函数。
符号是一种原子。当列表的第一个元素是符号原子时,Emacs Lisp 解释器就会认为这是一个函数求值表达式。
在 Emacs Lisp 符号原子有许多用途,可是它的主要用途是做为函数的名字,而且做为 Emacs Lisp 断定一个表达式是否为函数求值表达式的特征。
如今,我问你一个问题,
(defun hello-world () (interactive) (insert "hello, world"))
这块代码,是否是一个列表?
古希腊哲学家德谟克利特说,万物的本原是原子与虚空。原子是不可再分的物质微粒,虚空是原子运动的场所。
咱们已经大体见识了 Emacs Lisp 中的一些原子,那么对于由原子构成的程序而言,虚空是什么?
是 Emacs Lisp 解释器。
因为我坚信 Emacs 是一台计算机,那么虚空就是这台计算机的 CPU。
假若你如今认为本身不过是一个程序,本身的身体由一堆原子构成,那么这个宇宙一定有一个 CPU 之类的东西存在……为了增长一点东方神秘气息,打开《道德经》,应该能找到对这个 CPU 的描述:有物混成,先天地生。寂兮寥兮,独立不改,周行而不殆,能够为天地母。
请不要想太多,不然……后果自负。
下一篇: 周而复始