先贴张图膜拜一下
1958年,John McCarthy设计了Lisp,半个世纪过去了,而今最新潮的语言也只是实现了lisp的设想。虽然流行程度不是很高,但对Lisp的评价却是颇高。lisp究竟是一门什么样的编程语言?
Lisp名称源自列表处理(LISt Processing)的英语缩写,是基于λ演算所创造的。McCarthy的本意并不是要设计一门编程语言,而是要做一种理论演算,用更简洁的方式定义图灵机。
Lisp在设计之初就有过人之处:
- 条件结构(即"if-then-else"结构)。现在大家都觉得这是理所当然的,但是Fortran I就没有这个结构,它只有基于底层机器指令的goto结构。
- 函数也是一种数据类型。在Lisp语言中,函数与整数或字符串一样,也属于数据类型的一种。它有自己的字面表示形式(literal representation),能够储存在变量中,也能当作参数传递。一种数据类型应该有的功能,它都有。
- 递归。Lisp是第一种支持递归函数的高级语言。
- 变量的动态类型。在Lisp语言中,所有变量实际上都是指针,所指向的值有类型之分,而变量本身没有。复制变量就相当于复制指针,而不是复制它们指向的数据。
- 垃圾回收机制。
- 程序由表达式(expression)组成。Lisp程序是一些表达式区块的集合,每个表达式都返回一个值。这与Fortran和大多数后来的语言都截然不同,它们的程序由表达式和语句(statement)组成。ruby就采用了这种机制
- ...
《黑客与画家》内有一段:“至于Ruby,如果回到1975年,你声称它是一种Lisp方言,没有人会反对”。作为一个ruby程序员,应该对Lisp有所了解。
Lisp的语法很简洁,几乎就是他的名字-表处理,程序代码与数据的形式完全相同,以圆括号为边界的表。插一个笑话:说苏联和美国太空竞赛的时候,克格勃费劲千辛万苦,从NASA偷了一页的源代码,拿回去一看,好嘛,是Lisp代码的最后一页,满纸都是 “)”。
闲话少说,下面来一些干货,介绍一下lisp的语法:
1 表达式
如上所说,Lisp的表达式其实就是“表”
123 ;值是表达式
(+ 3 2) ;操作符在前,后边参数以空格隔开
(+ 3
(* 10 12)) ;组合式 3+ (10 * 12)
2 命名
以Scheme(Lisp方言,下同)为例
(define size 2)
,定义变量size并赋值2
3 定义过程
过程定义形式一般如下:
(define (<名字> <参数(可多个)>) (<实现>))
例如(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))
效果如下: