前一篇《 勤勞,仍是懶惰?》講述了編程的目的在於讓本身或者別人更省力地完成一些重複性的勞動。從這篇文章開始,正式學習 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 的描述:有物混成,先天地生。寂兮寥兮,獨立不改,周行而不殆,能夠爲天地母。
請不要想太多,不然……後果自負。
下一篇: 周而復始