Lisp 入門
LISP 是 LISt Processor 的縮寫,是“列表處理語言”意思。
Lisp語言最初是由美國的 John McCarthy 在 1958 年提出來的,是最早的計算機語言之一。然而,半個多世紀后的今天,Lisp 語言仍然在使用,並且還會繼續被使用,這和它獨特的結構是分不開的。Lisp的基本框架可以容下任何修訂或擴充。而且 LISP 語言在符號處理方面的優勢,LISP 最初使用於人工智能處理。(早期有部分人工智能的研究者認為:“符號演算系統可以衍生出智能。”)
《黑客與畫家》的作者 Paul Graham 就對 Lisp 語言贊譽有加,認為大部分的現代語言都在向 Lisp 靠近。
安裝 Mac 環境
在已安裝 HomeBrew 前提下
在 Terminal 鍵入
brew install sbcl
開始
Terminal 中鍵入
sbcl
會有
This is SBCL 1.4.6, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
*
這個就是 Lisp 的解釋器,在這里我們首先要知道退出是 (quit)。
解譯器的功能就是對一個輸入的表達式求值的東西。
函數
在 Python 中1+2
1 + 2
而在 Lisp 中1+2
(+ 1 2)
在Python中 + 是運算符,而在 Lisp 中 + 是運算符,同時也是函數,但它是前綴表達。
在數學中,一聽到函數就是 f(x) 或者 f(x,y),而 Lisp 中我們會表示成
(f x)
(f x y)
加法可以看成一個二元函數寫作
+(1, 2)
而在 Lisp 中寫作
(+ 1 2)
在上面已經出現過。
Lisp 7大公理
- Quote(‘)
- Atom
- Eq
- Car
- Cdr
- Cons
- Cond
所謂說7大公理,就是說所有 Lisp 中的函數均能用以上7個表達式或者說函數來表達。
Qutoe 函數能防止 Lisp 對括號內的內容(括號內的內容又稱為Lisp的列表)求值。
Eq 函數只能對原子求是否相同。
一些函數和結果
(car '(1 2 3));;;1 # 實際是取二叉樹的左支
(cdr '(1 2 3));;;(2 3) # 實際是取二叉樹的右支
;;;一些雞賊的表達
(cadr '(1 2 3));;;2 # 相當於(car (cdr '(1 2 3))
(caddr '(1 2 3));;;3
(cons 1 '(2 3));;;(1 2 3) # 合並表
(cons 1 2);;;(1 . 2) # . 用於區分二叉樹的左支和右支,所以實際上表是二叉樹
(cons '(1 2) '(3 4));;;((1 2) 3 4) # 省略了 . 但 (1 2) 依舊是左支
(append '(3 3) '(4 4));;;(3 3 4 4)
(append '((3)) '(4 4));;;((3) 4 4) # 所以 append 是去掉一層括號然后合並
(list 1 2 3 4);;;(1 2 3 4)
(list '(1 2) '(3) 4);;;((1 2) (3) 4) # List 是把所有參數放入一個表中返回
(first '(1 2 3));;;1
(last '(1 2 3));;;(3)
Lisp中有一個叫原子的東西,還不清楚是什么,反正不可再分,是一個很基礎的概念。
原子可以是任何數,分數,小數,自然數,負數等等。
原子可以是一個字母排列,當然其中可以夾雜數字和符號。
空表就是原子NIL。在 LISP 解釋器中輸入引用符(單引號)緊接着輸入一個原子,可以返回這個原子本身,就像對列表的操作一樣。即:
'abc;;;abc
好像是除了表和所有函數以外均是原子。
(atom (+ 1 1));;;T
(atom '(3));;;nil
(atom nil);;;T
SETQ運算符
Setq 可用於隱性設定全局變量,而 Let 可設置局域變量
鍵入
a
會報錯「The variable A is unbound.」
再鍵入
(setq a 5);;;5
然后鍵入
a;;;5
斷言函數
atom 判是否原子
null 判是否nil
equal 判是否相同
除此之外還有
Listp 判是否列表
在 Lisp 中有許多判斷均已 P 結尾,而且均為斷言函數。P 即 Predicate
Lisp 中一切非空(nil)一般為真
(null nil);;;T
(equal 's 's);;;T
Cond 操作符(定理)
(cond 分支列表1 分支列表2 … 分支列表N)
分支列表的構成: (條件P 值e)
cond 將對每一個條件P求值,如果為Nil就接着求下一個分支列表;如果為T,就返回對應的『值e』;如果沒有一個真值(T),cond 操作符就返回Nil。
自定函數
DEFUN
例:
(defun 2nd (x) (car (cdr x)) )
(2nd '(1 2 3));;;2
七大公理的牛逼之處
所有函數均有七大公理衍生出來
Null函數
(defun null2 (x) (cond ((equal x nil) t) (t nil) ) )
And函數
(defun and2 (x y) (cond ((equal x nil) nil) ((not (equal y nil)) t) (t nil) ) )
Or函數
(defun or2 (x y) (cond ((equal x t) t) ((equal y t) t) ) )
Last 函數
(defun last2 (x) (cond ((equal (cdr x) nil) x) (t (last2 (cdr x))) ) )
Length函數
(defun len (x) (cond ((null x) 0) (t (+ (len (cdr x)) 1)) ) )
Append函數
(defun append2 (x y) (cond ((eq x nil) y) (t (cons (car x) (append2 (cdr x) y))) ) )
Equal函數
(defun equal2 (x y) (cond ((null x) (not y)) ((null y) (not x)) ((atom x) (eq x y)) ((atom y) (eq x y)) ((not (equal2 (car x) (car y))) nil) (t (equal2 (cdr x) (cdr y))) ) )
If函數
(defun if2 (p e1 e2) (cond (p e1) (t e2) ) )
參考來源
《ANSI Commons Lisp》
Lisp入門