閱讀580 返回首頁    go 阿裏雲 go 技術社區[雲棲]


我也說說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

  上一篇:go  STS(Eclipse)+Maven將war項目部署到遠程的tomcat
  下一篇:go  Docker用以提高Linux內核安全性的三大熱點技術