一个程序的函数元素不能太大是一个长期存在的编程风格原则。若是程序的某些组件增加到读难以理解的成都,它就变成一大堆的复杂东西,它们隐藏错误就像一个大城市隐藏逃亡者同样简单。这样的软件将很难读、很难测试、很难杀臭虫。程序员
遵循这个原则,一个大的程序必须被分红不少片,一个程序越大,就须要被越多地分割。你怎样分割一个程序呢?传统的方法是自上而下的设计:你说“这个程序的目的是作这7件事情,因此我把它分红7个子功能”等等。这个过程持续到整个程序有正确水平的粒度——每块均可以独立地作一些事情,可是可以做为一个单元小到能够读懂。编程
有经验的Lisp程序员以不一样的方式来分割他们的程序。就像自上而下的设计,他们遵循自下而上的设计——改变语言以适应问题。在Lisp中,你不只仅是根据语言去写你的程序,你也根据你的程序区创建语言。当你正在写一个程序的时候,你可能想"我但愿Lisp有这样这样的操做符",因此你就去写它。以后,你意识到使用新的操做符将简化程序其它部分的设计,等等。语言和程序一块儿演进。就像两个正在战争的国家的边界同样,语言和程序的边界被不断地重画,知道最后沿着山脉和河流,你问题的天然边缘。最后你看的程序,就像这门语言就是为它设计的同样。党语言和程序相互协调很好,你获得的将是清晰、小巧和高效的代码。函数
值得强调一下,自下而上的设计不只仅意味着以不一样的顺序写同一个程序。当你自下而上的工做,你一般最后会获得一个不一样的程序。你将获得一个拥有更多抽象操做符的更大的语言和用它写的更小的程序,而不是单一的、庞大的程序。你将获得一个拱门,而不是一个横梁。工具
典型的代码中,一旦你抽象出仅仅记帐的部分,剩下的就很简短了;你在越高的层级上创造语言,贯穿它所需的距离就越少。这带来了几个好处:测试
1. 经过让语言作更多的工做,自下而上的设计产生的程序更加小巧和敏捷。一个小的程序没必要要被分红那么多的组件。越少的组件也意味着组件之间的关系也越少,也就意味着那里有更少的机会出错。工业设计人员尽量减小机器中须要移动的部分,有经验的Lisp程序员使用自下而上的设计来减小程序的体积和复杂度。设计
2. 自下而上的设计提高了代码的可重用性。当你写两个或者更多程序时,为第一个程序写的一些工具对随后的程序也颇有用。一旦你拥有了大量的工具,在你开发一个新程序的时候花费的精力只有用原生的Lisp的一小部分。开发
3. 自下而上的设计使得程序更加易读。这种类型的抽象让读者理解一个通用的操做符;函数抽象让读者去理解一个特定的子功能。程序设计
4. 由于它使得你一直关注于你代码的模式,自下而上的工做会帮助你澄清你程序设计的想法。若是两个相隔较远的模块在形式上是类似的,你将被引导注意到这种类似性,可能你就会从新以一种更简单的方式来设计这个程序。扩展
自下而上的设计在非Lisp语言中也能够在必定程度上实现。当你看到库函数的时候,就是在进行自下而上的设计。然而,Lisp在这方面给与你更宽广的力量,而且使语言在Lisp风格的上扮演愈来愈重要的角色——Lisp不只仅是一种不一样的语言,也是一种彻底不一样的编程方式。软件
这种开发风格适合于那种能够分红几个小组来开发的程序。然而,同时,它扩展了一个小模块的限制。人月神话中,Frederick Brooks指出一个小组的的生产力和程序员的数量不成正比。随着小组的扩大,每一个程序员的生产力开始降低。Lisp编程的经验以一种愉快的方式来表达这个规则:随着组的缩小,每一个程序员的生产力上身。一个小组成功,相对来讲,仅仅是由于它小。当一个小组能够利用Lisp所带来的技术时,它能够一会儿成功。