我也說說Emacs吧(7) - lisp基礎
lisp基礎
Lisp是僅次於Fortran的第二古老的著名計算機語言。
Lisp從一開始就與眾不同的一點在於,它是基於S-表達式的語言。也就是說,代碼和數據是用同一種方式表達出來的。
S-表達式,我們直觀上理解,就是用括號括起來的一串列表。
比如:
(+ 1 1)
Lisp會對這個S-表達式進行求值。
S-表達式可以嵌套,比如可以這樣寫
(+ 1 (* 2 3))
在lisp中,默認的操作是對S-表達式求值。如果是個數字,就對數字直接求值。如果是字符串也是如此。如果是個表,則將第一個原子當成函數名,對其進行求值。
那麼,如果我們隻想將一個S-表達式當成數據,不要計算怎麼辦?我們可以使用quote符號來進行指定,比如:
(quote (+ 1 2))
結果就返回(+ 1 2)這個列表。
quote在lisp中實在是太常用了,所以我們可以用符號“’”來作為它的簡稱。
定義變量
大家都是寫代碼的老司機啦,我們就直接從定義變量開始說起。
定義變量可以使用set函數。
(set 'three (+ 1 2))
要注意,因為變量名是不求值的,所以要用quote或者'來阻止求值。將來用變量的值的時候就不用quote了。
定義變量的時候,符號是基本上不可能用求值的,所以'是基本上必須的。每次寫太麻煩,於是專門有個setq特殊表,直接包含了對於第一個參數的不求值的quote行為。
定義局部變量:let特殊表
let可以定義局部變量。let定義的綁定隻在函數內部起作用。
格式:
(let ((變量名 綁定值)(變量名 綁定值)) 語句)
例:
(let ((a 1)(b 2)) (+ a b))
a被賦值1,b被賦值2.最終表達式結果是3.
在let中,如果未指明綁定值,則自動綁定到nil上。
注釋
emacs的注釋以分號開頭,分號之後全是注釋。
表處理
car和cdr:取表頭和其餘部分
下麵我們開始進入lisp不同於命令式語言的一個特色功能,表處理。
- car函數:取一個表的第一個元素
- cdr函數:取一個表的除了car取到部分的其它部分
例:
(car '(1 2 3))
將返回1.
(cdr '(1 2 3 4 5))
取得的結果是(2 3 4 5)
nthcdr函數:多次cdr
如果我們要從(1 2 3 4 5)這個表中取(3 4 5)這樣的子表,一次cdr不夠,需要做兩次,像這樣:
(cdr (cdr '(1 2 3 4 5)))
有個更簡單的寫法是使用nthcdr函數:
(nthcdr 2 '(1 2 3 4 5))
nthcdr的第一個參數,如果是0,則直接返回原表。如果是1,則退化成cdr。
cons函數:將car和cdr拚接起來
cons是car和cdr的逆運算。將兩個表拚接成一個新表。
例:
(cons '1 '(2 3 4))
將得到(1 2 3 4).
請注意,cons會將第一個參數當成一個元素處理。
比如:
(cons '(1 2 3) '(4 5 6))
得到的結果不是(1 2 3 4 5 6)而是((1 2 3) 4 5 6)
求表長度:length函數
例:
(length '(1 2 4 5))
結果為4.
給表換car和cdr:setcar和setcdr函數
例:
(setq list1 '(1 2 3 4))
(setcar list1 5)
此時再通過C-h v去查list1的值,已經變為(5 2 3 4).
我們再將其後部也換掉:
(setcdr list1 '(6))
list1此時的值已經變成(5 6)
小結
- setq特殊表:定義變量
- let特殊表:定義函數內部的局部變量
- car和cdr,nthcdr:取表頭和其餘部分
- const: 構造新表
- setcar, setcdr: 給表換頭或換其餘部分
最後更新:2017-06-13 17:31:40