第1章 引言:软件和编程艺术的兴起(2)
战后,软件业作为一个探索领域、一个行业以及通信与商业之间的媒介,取得了令人瞩目的迅速发展,而这一切几乎都发生得悄无声息。计算机编程的起源至少可追溯到19世纪。当时英国数学家查尔斯·巴贝奇正致力于解决分析机的计算问题;分析机是现代计算机概念化的雏形。今天,我们可以将其所做的事情称为编程。编程中最基本的概念是算法,即执行某种操作的一组指令,或者说是计算的方法。追根溯源的话,算法(algorithm)最早出现在巴比伦[3],而algorithm这个词则是对波斯学者Muhammad ibn Musa al-Khwarizmi[4]姓氏的讹传,他写过一篇关于代数方法的专著。
但是,在第二次世界大战之前,电子技术还不够先进,人们尚未开发出有用的计算机。早期的编程只是后期任务的附属工作,更像是技术人员烦琐的劳动,通常被认为是机器的“设置”或“编码”。真正吸引人的是硬件,因为它被认为是真正的科学和工程。人们普遍认为,电子数字集成器和计算器,即ENIAC(Electronic Numerical Integrator and Computer),才是开启数字电子计算时代的关键所在。其实,这台存放于宾夕法尼亚大学的机器只是一台裸机。操作人员必须对这台机器进行手动设置,插拔那些让人眼花缭乱的线缆,并把一排一排的开关放到正确的位置。每解决一个新问题似乎都要重建机器,因为它采用的是硬接线方式。为此,当局雇用了一些具备数学技能的年轻女士,并对她们进行了培训。这些女性程序员称为“计算员”(computer),这个词可追溯至18世纪,专门指那些为绘制地图或航海图而编制统计表的计算者。
对ENIAC进行编程,使其计算出火炮的弹道轨迹,这是一项艰难的工作,但却是美国国防部指定的任务。为此,这些女程序员想出了一些技巧来简化流程。她们先在纸上画出详尽的图表,并标出在这台机器上可以解决问题的最有效方法。然后,她们再对机器进行手动设置。珍·巴蒂克这样回忆道[5]:“我们清楚地知道如何设置每一条线和每一个开关。”这种操作可能会花费好几个星期的时间。不过,正是由于她们的努力,ENIAC的公开演示才获得了巨大成功:一条炮弹轨迹用很短的时间就能计算出来,比炮弹本身的飞行速度还快。巴蒂克回忆道:“那简直棒极了,是我一生中最激动的一天。”[6]当时已是战后,1946年的春天。
对于新兴职业的从业者来说,他们的职业称谓变化很快。人工的“计算员”(computer)变成了“编码员”(coder),然后,这个平淡无奇的称谓又被“程序员”(programmer)势不可当地取代了。事实上,这是英国从业者的贡献。很明显,新称谓听起来更有身份,也更具文学气息。葛丽丝·霍普是软件方面的领军人物,于1944年开始在哈佛Mark I上从事战备方程式的计算。她一直认为,用“编程”(programming)这个词来形容初期的工作过于高尚。“直到从英国传过来,‘程序员’这个词才开始广泛使用。”她回忆道,“事实上,我认为,书写机器代码的过程就是编码,我们应该留着‘编程’这个词来描述更高一级的工作。但是,它是从英国传过来的,而且比编码员要好听得多,于是每个人都想被称为程序员。”[7]
由于计算机设计上的突破,更高一级的编程很快就成为现实。这个想法最初源于ENIAC工作团队,随后,1945年6月发表的由约翰·冯·诺依曼撰写的文章“关于EDVAC的报告初稿”(A First Draft of a Report on the EDVAC)对其进行了详尽的阐述。作为著名的数学家和博弈理论家,冯·诺依曼受聘担任原子弹开发项目“曼哈顿计划”的顾问。原子弹的设计需要成千上万次的计算,当时主要是由大量计算员借助台式计算机来完成的。计算机的潜力引起了冯·诺依曼的兴趣,于是他在1944年成为了ENIAC项目的顾问。后来,在ENIAC的基础之上,经过改进,又有了EDVAC(Electronic Discrete Variable Automatic Computer),即电子离散型变量自动计算机。除了冯·诺依曼,还有很多人参与设计了EDVAC,其中最为著名的便是ENIAC项目负责人J. 普雷斯普尔·埃克特和约翰·莫克利,但由于最终负责撰写报告的是冯·诺依曼,因此他获得了设计“存储程序式计算机”的殊荣。这种设计思路就是后来广为人知的冯·诺依曼架构。事实上,现在所有的计算机使用的都是冯·诺依曼架构。
第二次世界大战后,早期的存储程序式计算机才真正开始出现。存储程序的理念在于,不仅计算机的数据——当时用于计算的主要是数字——而且程序指令也会存储在机器中。从某种程度上来说,这无疑能够提高效率,并能实现计算自动化。由于程序指令可以设置到打孔卡片或纸带上,与将要处理的数据一起存入计算机中,所以,再也不用手动设置开关和线缆了。
然而,存储程序这个概念还有更深刻的含义。用计算机科学家巴特勒·兰普森的话来说,它使软件构建成为了一门“独特的自引用”[8]工程学科,因为所有的计算机制都可以应用在自身中。也就是说,存储程序式计算机可使程序修改其他程序或创建新的程序。正是有了这种以计算机为中介的编程交互方式,如今的计算机编程语言才远远超越二进制0和1的组合,更易于人类理解。这种编程交互方式相当于计算机内部的数字生态环境:一段代码迅速跳到进程外去修改其他代码,而后者又会循环回来与其他代码混合。无论是电脑游戏、互联网,还是人工智能,所有这一切都源于代码的这种组合、重组以及持续地自我修正的能力。
早期存储程序式计算机的开发人员最早体会到了编程的复杂性,而且这种复杂性常常是无法预料的。剑桥大学的莫里斯·威尔克斯率领的团队制造了第一台存储程序式计算机,并投入运行。这台机器称为EDSAC(Electronic Delay Storage Automatic Calculator,电子延时存储自动计算器)。在回忆录中,威尔克斯还清楚地回忆起第一次认识到bug注定是程序员的克星时的情景。他这样写道:“到了1949年6月,人们已经意识到,要得到正确无误的程序并不像看起来那么容易。”[9]当时,威尔克斯正在研究他的第一个“重大项目”,而当他在剑桥大学的事业更上一层楼时,他回忆道:“我突然强烈地意识到,我接下来的时间都要花费在寻找程序的bug上了。”