先貼張圖膜拜一下
1958年,John McCarthy設計了Lisp,半個世紀過去了苛蒲,而今最新潮的語言也只是實現(xiàn)了lisp的設想。雖然流行程度不是很高绿满,但對Lisp的評價卻是頗高臂外。lisp究竟是一門什么樣的編程語言?
Lisp名稱源自列表處理(LISt Processing)的英語縮寫喇颁,是基于λ演算所創(chuàng)造的漏健。McCarthy的本意并不是要設計一門編程語言,而是要做一種理論演算橘霎,用更簡潔的方式定義圖靈機蔫浆。
Lisp在設計之初就有過人之處:
- 條件結構(即"if-then-else"結構)。現(xiàn)在大家都覺得這是理所當然的姐叁,但是Fortran I就沒有這個結構瓦盛,它只有基于底層機器指令的goto結構洗显。
- 函數(shù)也是一種數(shù)據(jù)類型。在Lisp語言中原环,函數(shù)與整數(shù)或字符串一樣挠唆,也屬于數(shù)據(jù)類型的一種。它有自己的字面表示形式(literal representation)嘱吗,能夠儲存在變量中玄组,也能當作參數(shù)傳遞。一種數(shù)據(jù)類型應該有的功能谒麦,它都有俄讹。
- 遞歸。Lisp是第一種支持遞歸函數(shù)的高級語言绕德。
- 變量的動態(tài)類型患膛。在Lisp語言中,所有變量實際上都是指針迁匠,所指向的值有類型之分剩瓶,而變量本身沒有。復制變量就相當于復制指針城丧,而不是復制它們指向的數(shù)據(jù)延曙。
- 垃圾回收機制。
- 程序由表達式(expression)組成亡哄。Lisp程序是一些表達式區(qū)塊的集合枝缔,每個表達式都返回一個值。這與Fortran和大多數(shù)后來的語言都截然不同蚊惯,它們的程序由表達式和語句(statement)組成愿卸。ruby就采用了這種機制
- ...
《黑客與畫家》內(nèi)有一段:“至于Ruby,如果回到1975年截型,你聲稱它是一種Lisp方言趴荸,沒有人會反對”。作為一個ruby程序員宦焦,應該對Lisp有所了解发钝。
Lisp的語法很簡潔,幾乎就是他的名字-表處理波闹,程序代碼與數(shù)據(jù)的形式完全相同酝豪,以圓括號為邊界的表。插一個笑話:說蘇聯(lián)和美國太空競賽的時候精堕,克格勃費勁千辛萬苦孵淘,從NASA偷了一頁的源代碼,拿回去一看歹篓,好嘛瘫证,是Lisp代碼的最后一頁揉阎,滿紙都是 “)”。
閑話少說痛悯,下面來一些干貨余黎,介紹一下lisp的語法:
1 表達式
如上所說重窟,Lisp的表達式其實就是“表”
123 ;值是表達式
(+ 3 2) ;操作符在前载萌,后邊參數(shù)以空格隔開
(+ 3
(* 10 12)) ;組合式 3+ (10 * 12)
2 命名
以Scheme(Lisp方言,下同)為例
(define size 2)
巡扇,定義變量size并賦值2
3 定義過程
過程定義形式一般如下:
(define (<名字> <參數(shù)(可多個)>) (<實現(xiàn)>))
例如(define (square x) (* x x))
就定義了square過程,可以求平方(square 3)
會得到9
4 條件表達式
條件表達式的一般過程如下
求x絕對值為例
(cond ((> x 0) x)
((= x 0) 0)
((< x 0 ) (- x)))
;也可以這樣
(cond ((< x 0) (- x))
(else x))
;還可以這樣
(if (< x 0)
(- x)
x)
邏輯復合運算符 and or not
(and (> x 0) (< y 0))
(or (> x 0) (< y 0))
了解了以上知識扭仁,下面我們來個稍微復雜點的練習,用牛頓迭代法求平方根
;先定義判斷已求的平方根是不是已夠精確
(define (good-enough? guess x)
(< (abs (- x (square guess))) 0.001))
;定義無限逼近的方法
(define (average x y)
(/ (+ x y) 2))
;定義改進方法
(define (improve guess x)
(average guess (/ x guess)))
;定義求平方根遞歸
(define (sqrt-item guess x)
(if (good-enough? guess x)
guess
(sqrt-item (improve guess x)
x)))
;定義求平方根方法
(define (sqrt x)
(sqrt-item (/ (* 1.0 x) 2)
x))
效果如下: