在20世纪40年代和50年代初时,编写代码是一件非常困难的事。人们不得不学习机器语言,同时还要知道寄存器的大小和数量,有时候,事情不妙,还要拿起螺丝刀亲自上场①,去连接计算单元的信号线。人们的主要精力不在于思考一个算法,而放在将算法编写成可执行程序上,这是一种枯燥又机械的工作。
FORTRAN语言的出现,就像天使为人间送来了福音。与经验主义者相同,它允许程序员只关心数学公式的计算,而无须考虑其他的内容。程序员可以完全不用了解汇编语言,也不用再关心计算机内部的技术细节。他们完全可以把这些琐碎的事情丢到一边,更专注于更重要的事情,如如何将数学公式写成相应的算法步骤交给计算机进行运算。FORTRAN语言简化了软件开发过程,几乎没有什么东西是不能用FORTRAN来处理的,这是经验主义者的一个巨大成功。
只不过,编码仍然不是一件简单的事情,它需要变得更加简单。为了解决这种矛盾,由此又产生了一些新语言(如COBOL②),大家打出的口号是“新手就能学”、“管理层也能读懂”之类的,进一步简化一些特殊任务的编码工作。虽然到了今天,已经没有人会考虑用COBOL编写一个新的系统。然而,在那时候,COBOL与汇编或者FORTRAN语言相比,能大大简化对数据库的操作。经验主义风头更甚。
并非所有人都喜欢经验主义。始终会有人认为,万事万物都应该是合理的。我们身边肯定有这类人,程序员也不例外。在20世纪50年代,理性主义者约翰•麦卡锡(John McCarthy)在演算③的数学模型的基础上发明了LISP④语言,演算的数学模型包含了大量的理论知识。数学是一门纯理性学科,因此,LISP完全由纯粹的推理来支持的。据说,在设计LISP语言时,很多人认为,保持数学的纯洁性是最重要的。多么执著的理性主义者!他们认为语言无须是有用的,甚至无须是可实现的,但它必须是纯粹、干净且合理的。
所以,有人认为计算机科学可以分成两大学派,欧洲派和美国派。美国人通常更加务实一些(的确如此,历史上的美国是实用主义的发源地),而欧洲人则更愿探索远景。在计算机工程界也能发现这一特点。很多示例表明欧洲人更倾向于理性主义而轻视实用主义。Edsger W. Dijkstra,这位基于消息的计算和信号量同步模式的发明者,在Selected Writings on Computing⑤中写道:从他的角度出发,他认为“编程是一门数学味儿很浓的工程学科”。按照他的说法,我们应该坚持理性主义。然而,当我环顾四周,看看程序员编写的那些会计软件、医院所用的病患管理软件等,我就感觉其实写程序和做饭差不多,没有多少数学的内容在里面。当然,编写好的算法需要一定的数学背景。然而,Niklaus Wirth,这位发明了Pascal、Oberon和其他软件系统的大师,却认为:简单而且优雅的方案往往更加有效,只不过想找出这样的方案却很困难,需要更多的时间。这个说法当然没有问题,但在当前上市时间决定能否成功的年代,根本没有时间用来探寻最佳方案。
![](http://img3.douban.com/view/page_note/large/public/p12627305-1.jpg)
图1-1 我要编写HTML页面谋生
看来,在今天的软件工程世界中,理性主义已无存身之地。特别是现代的程序员,几乎没有几个推崇理性主义了。图1-1表明,我们已经完全丧失了秉持理性主义的程序员了。这并不新鲜,Dijkstra就曾经说过:“大部分程序员都没有能力编写出好的代码。”真理啊!现代社会不断地对软件业提出新的要求,但我们又可以做些什么呢?
对我们常人来说,基于理性主义还是经验主义去理解这个世界,其实无关紧要,最好的建议莫过于无知一点儿,同样,编写程序也是如此。这个世界,或者说我们现在所处的这个社会并不需要每个人都成为哲学家。这个社会给我们这些懂得少些也即更无绪的人留有空间,而一切也能正常。同样,软件工程也不要求所有的程序员都是受过高等教育的科学家。如果想开发软件,就需要一个系统,程序员可以无绪也能产生可靠的软件系统。
事实上,上文一直在说的无绪并不是说完全不懂编程。很明显,仅仅在键盘上随机地输入字符是不太可能产生一个可编译的程序的。所以对于程序员,知道如何编写代码是一个先决条件(就像人类社会中,人们必须具有观察、理解、讨论电视广告等能力一样)。在软件工程中所指的无绪是指程序员在不需要深入了解很多内容的情况下,就可以写出好的代码。这里不能简单地说哪些知识是必需的,而哪些则不是。我们的目标是找到一种编码实践方法,让开发人员不用深入了解所有事情,即选择他们所需的知识。我把这称为针对性无绪⑥。
① 早期计算机的软硬件并不像今天区分得这么清楚,很多工程师都是软硬通吃的人物,而且那个时候电子管计算机经常出故障,需要进行维修,像bug一词就来自于一个硬件故障。——译者注
② COBOL是Common Business Oriented Langauge的缩写,是最早的高级编程语言之一,是世界上第一个商用语言。
——译者注
③ 演算(lambda calculus)是一套用于研究函数定义、函数应用和递归的形式系统。它由阿朗佐•丘奇(Alonzo Church)和他的学生斯蒂芬•科尔•克利尼(Stephen Cole Kleene)在20世纪30年代引入。——译者注
④ LISP是由约翰•麦卡锡在1960年左右创造的一种基于演算的函数式编程语言,它是第一个函数型编程语言,主要应用在人工智能(AI)上,包含多字符撷取函数,供作自然语言的分析之用。——译者注
⑤ Edsger Dijkstra, Selected Writings on Computing: A Personal Perspective (New York: Springer-Verlag, 1982)。
⑥ 原文为selective cluelessness,直译为选择性无绪,这里翻译成针对性无绪。——译者注