永不过时的Lisp
有人认为Lisp是世界上最强大的编程语言,现在的编程语言正在向Lisp进化。有人可能会觉得奇怪,为什么计算机发展了几十年,编程语言的水平还不如一个1958年的Lisp?其实原因很简单,Lisp的设计者根本就没有打算Lisp设计成编程语言,至少不是我们现在意义上的编程语言。Lisp之父麦卡锡当年设计Lisp的目的在于用更简单的方式定义图灵机。Lisp也确实比图灵机表达起来更简洁。当1958年年底,麦卡锡的一个学生拉塞尔要把Lisp实现的时候,麦卡锡还告诉别把理论和实践混淆。由此也就得出为什么Lisp到现在还没有过时的原因了。因为这个种语言本质上是数学,而数学是不会过时的。
Fortran语言也是20世纪50年代出现的,一一直沿用至今,他代表了语言设计的一种完全不同的方向。Lisp语言是从纯理论发展成编程语言的,而Fortran从一开始就是作为编程语言设计出来的。换句话说,Fortran代表的是计算机的硬件构架,而Lisp代表的却是数学。从那时候起,两大方向就一直在互相靠拢,这也是为什么现在的语言正在向Lisp进化的原因。
其实如果把几种常见的语言进行排序:java Perl Python Ruby ,你会发现一个有趣的结果,那就是它们越来越像Lisp。甚至对于Ruby来说,在20世纪70年代,你可以说它就是一种有自己句法的Lisp方言。这里可以举个例子看说明这一点:写一个函数,接受一个参数n,然后返回另一个函数,后者接受参数i,然后返回n增加了i后的值。
Common Lisp的写法:
(defun foo(n)
(lambda (i) (incf n i)))
Ruby的写法:
def foo(n)
lambda {|i| n +=i} end
Perl 5的写法:
sub foo{
my ($n)=@_;
sub{$n+=shift}
}
Python的写法:
def foo(n):
s=[n]
def bar(i):
s[0]+=i
return s[0]
return bar
很遗憾的是java只能给出一个近似的的解法,而Fortran、C、C++这些语言根本无法解决,当然从图灵等价的角度上其实也可以,用这些语言写一个解释器还是可以解决的。
那么到底是什么让Lisp变得如此不同?下面将给出Lisp的九大特性:
(1)条件结构(if-then-else)。对!没错就是这个,第一个高级语言Fortran是没有这个结构,这个是Lisp首创。
(2)函数也是数据类型。Lisp是第一个支持函数式编程的语言,或者可以这么说Lisp本身就是基于lambda计算的。
(3)递归。Lisp也是第一个支持递归的高级语言
(4)变量的动态类型。在Lisp语言中,所有变量实际上都是指针,所指向的值有类型之分,变量本身没有.
(5)垃圾回收机制。对!没错,Lisp是第一个发明垃圾回收机制的高级语言。
(6)程序有表达式构成。Lisp程序由一些表达式数构的集合,每个表达式都返回一个值。
(7)符号类型。
(8)代码用符号和常量组成的树形表示法。
(9)无论什么时候,整个语言都是可用的。Lisp并不正真区别读取期、编译期和运行期。
其中1到5已经被广发接受,6已经在主流语言中出现,7在python有实现,8和9仍是Lisp独特。也正是8和9这两条特性造就了Lisp强大的特性,让你能写出一种能够自己编程的程序。
特别申明:本文主要摘自 Hackers and Painters 第13章,在此向作者表示致敬。