Lisp的诞生

  Common Lisp是1956年John McCarthy发明的Lisp语言的现代版本。Lisp在1956年被设计用于“符号数据处理” ,而Lisp这个名字本身就来源于其最擅长的工作:列表处理(LISt Processing)。从那时起,Lisp得到了长足的发展:Common Lisp很好地支持了一组常用的现代数据类型;将在第19章里介绍的状态系统提供了Java、Python和C++等语言的异常系统里所没有的充分灵活性;强大的面向对象编程支持;以及其他编程语言里完全不存在的一些语言机制。这一切怎么可能?地球上怎么会进化出如此装备精良的语言来?

  这么说吧,McCarthy曾经是(现在也是)一个人工智能(AI)研究者,他在该语言的最初版本里内置的很多特性使其成为了AI编程的绝佳语言。在AI繁荣昌盛的1980年代,Lisp始终是程序员们所偏爱的工具,广泛用于编写软件来求解包括自动定理证明、规划和调度以及计算机视觉在内的各种困难问题。这些问题都需要大量难于编写的软件;为了处理它们,AI程序员们需要一门强大的语言,而他们将Lisp发展成了这样一门语言。另外,冷战也起了积极的作用——五角大楼向国防部高等研究规划局(DARPA)投入了大量资金,其中的相当一部分给了那些研究诸如大尺度战场模拟、自动规划以及自然语言接口等问题的人。这些人也在使用Lisp并且持续地推进它以满足自身的需要。

  推动Lisp特性进化的动力也同样推动了其他相关领域的发展——大型的AI问题无论如何编码总是要吃掉大量的计算资源,而如果你按照摩尔定律倒推20年,你就可以想象80年代的计算资源是何等的贫乏了。Lisp工作者们不得不想尽办法从他们的实现中挤出更多的性能来。现代Common Lisp实现就是这些早期工作的结晶,它们通常都带有相当专业的可产生原生机器码的编译器。感谢摩尔定律,今天我们从任何纯解释型的语言里也能获得可接受的性能了,性能对于Common Lisp来说再也不是问题了。不过,读者在第32章里仍然可以看到,通过使用适当的(可选)变量声明,一个好的Lisp编译器所生成的机器码,完全可以跟C编译器的成果相媲美。

  1980年代也是Lisp机的年代,当时好几家公司(最著名的是Symbolics)都在生产可以在芯片上直接运行Lisp的计算机系统。Lisp因此成了系统编程语言,被广泛用于编写操作系统、编辑器、编译器,以及Lisp机上的大量其他软件。

  事实上,到了1980年代早期,几家AI实验室和Lisp机厂商都提供了他们自己的Lisp实现,众多的Lisp系统和方言让DARPA开始担心Lisp社区可能走向分裂。为了应对这些担忧,一个由Lisp黑客组成的草根组织于1981年成立,旨在集既有Lisp方言之所长,定义一种新的称为Common Lisp的标准化Lisp语言。最后他们的工作成果被记录在Guy Steele的《Common Lisp: the Language》(CLtL)一书里,该书相当于Lisp的圣经。

  到1986年的时候,首批Common Lisp实现诞生了,它们是在Common Lisp试图取代的那些方言的基础上写成的。1996年,美国国家标准化组织(ANSI)发布了一个建立在CLtL之上并加以扩展的Common Lisp标准,其中增加了一些主要的新特性,包括CLOS和状态系统。但事情还没结束:跟此前的CLtL一样,ANSI标准有意为语言实现者保留了一定空间以试验各种最佳的工作方式。一个完整的Lisp实现将带有丰富的运行时环境,并提供GUI接口、多线程控制和TCP/IP套接口等。今天的Common Lisp则进化得更像其他的开源语言——用户编写他们所需要的库并开放给其他人。在过去的几年里,开源Lisp库领域尤为活跃。

  所以,一方面Lisp是计算机科学领域的“经典语言”之一,其建构在经过时间考验的各种思想之上。 另一方面,它完全是一门现代的通用语言,其设计反映了尽可能高效和可靠地求解实际问题的实用主义观点。Lisp“经典”遗产的唯一缺点是许多人仍然生活在片面的Lisp背景之下——他们可能只是在McCarthy发明Lisp以来的近半个世纪中某些特定时刻接触到了这门语言的某些方面。如果有人告诉你Lisp只能被解释执行,因此会很慢,或者你不得不用递归来干每件事,那么一定要问问他们究竟在谈论哪个Lisp方言,以及他们是否是在远古时代学到这些东西的。

  但是我曾经学过Lisp,不过跟你所描述的不太一样

  如果你以前用过Lisp,你对“Lisp”的认识很可能对学习Common Lisp没什么帮助。尽管Common Lisp取代了大多数它所继承下来的方言,但它并非仅存的Lisp方言,并且取决于你在何时何地认识了Lisp,你很有可能学的是某种其他方言。

  除了Common Lisp以外,另一种仍然有着活跃用户群的通用Lisp方言是Scheme。Common Lisp从Scheme那里吸收了一些重要的特性但从未试图取代它。

  Scheme最早在M.I.T.被设计出来,然后很快被用作本科计算机科学课程的教学语言,它总是被定位成一种比Common Lisp更加优美但又不同的语言。特别是Scheme的设计者们将注意力集中在使其语言核心尽可能地小而简单。这对作为教学语言来说非常有用,编程语言研究者们也很容易形式化地证明语言本身的有关命题。

  这样设计的另一个好处是使得通过标准规范理解整个语言变得相对简单。但是,这样做带来的问题是它缺失了许多在Common Lisp里已经标准化了的特性。个别的Scheme实现者们可能以实现相关的方式提供了这些特性,但它们在标准中的缺失使得编写可移植的Scheme代码比编写可移植的Common Lisp代码更加困难。

  Scheme同样强调函数式的编程风格并且比Common Lisp使用更多的递归。如果在大学里学过Lisp并且感觉它只是一种没有现实应用的学术语言的话,那你八成是学了Scheme。当然,说Scheme具有这样的特征并不是很公正,只不过同样的说法用在Common Lisp身上更加不合适罢了,后者专门被设计成真实世界的工程语言而不是一种理论上的“纯”语言。

  如果你学过Scheme,你也应该当心Scheme和Common Lisp之间的许多细微差别可能会绊你一跤。这些差别也是Common Lisp和Scheme社区的狂热份子之间的一些长期宗教战争的导火索。日后随着我们讨论的深入我将指出其中最重要的那些差别。

  另外两种仍然广泛使用的Lisp方言是Elisp——Emacs编辑器的扩展语言,以及Autolisp——Autodesk的AutoCAD计算机辅助设计工具的扩展语言。尽管用Elisp和Autolisp可能已经写出了超过任何其他方言的代码行数,但它们都不能用在各自的宿主应用程序之外,而且它们无论与Scheme还是Common Lisp相比都是相当过时的Lisp了。如果你曾经用过这些方言的一种,就需要做好准备,你可能要在Lisp时间机器里向前跳跃几十年了。


你可能感兴趣的:(Lisp的诞生)