Lisp风格的编程是随着软件复杂度的增长而增长的。高端用户现在要求程序做那么多的事情,以至于我们不能满足他们所有的需求。他们自己也不能完全满足他们自己的需求。但是如果我们不能给他们满足他们完全需求的软件,我们可以给他们可扩展的软件。我们将我们的软件从一个单一的程序编程一个编程语言,高端的用户可以在此基础上增加他们需要的功能。
自下而上的设计自然地产生可扩展的程序。最简单的自下而上的程序包含两层:语言和成语。复杂的程序可以被写成一系列的层,每一层对于它上面的那层来说都是一种编程语言。如果这种哲学自始至终地贯彻到最高层,最高层就变成为用户提供的一种编程语言。这样一个程序,它的可扩展性弥漫在每一层中,比传统的写一个黑盒的系统更能够制造出一种更好的编程语言,然后,扩展之类的事情可以留在后来想。
XWindows和TEX是早期的基于这个原则的编程实例。20世纪80年代,更好的硬件催生了新一代的程序,这些程序可以使用Lisp作为它们的扩展语言。第一个是Gun Emacs,流行的Unix文本编辑器。后来是Autocad,第一个用Lisp作为扩展语言的大规模商用产品。1991年,Iterleaf发布了一个新版本的软件,不仅仅用Lisp作为它的扩展语言,并且软件本身也大量地用Lisp来实现。
Lisp是一个特别适合写扩展性程序的语言,因为它自身就是一个可扩展的程序。如果你写你的Lisp程序,将这种可扩展性传递给你的用户,你就免费、高效地获得了一个可扩展的语言。在Lisp中扩展Lisp程序和在传统语言中做同样事情之间的不同,就像会见一个真人和用信件交流之间的不同。一个简单地通过让外界程序访问实现扩展性的程序,我们最大的期待就是两个黑盒可以通过事先定义好的通道进行通信。在Lisp中,扩展可以直接访问整个底层程序。这并不是说你必须让你的用户访问你程序的每一个部分——仅仅是说你现在有个选择,来决定是否让他们访问。
如果这种程度的访问于一个交互环境集成起来,你就得到最好的扩展性了。任何你想将你的扩展建于其上的程序很可能相当大——可能太大了,你可能要对它有个大致框架的掌握。当你对某些事情不确定的时候会发生什么呢?如果原来的程序使用Lisp写的,你可以交互地探进它:你可以观察它的数据结构;你可以调用它的函数;你甚至可以看源代码。这种回馈机制使得你在编程的时候更有信心——写出更多牛逼的扩展,更快地写出它们。一个交互式的环境总是使编程更加容易,但是它的价值莫过于写扩展。
一个可扩展的程序是一把双刃剑,但是最近的经验说明用户喜欢双刃剑的钝面。可扩展程序看上去占优势,不论它们的继承危险。