《编程的修炼》译者序

E.W.Dijkstra原著,裘宗燕译(电子工业出版社,2013.7)



返回书籍首页

图灵奖获得者Edsqer W. Dijkstra(1930.5.11-2002.8.6)是每个在计算机领域中学习和工作的人都应该了解和尊重的先驱者,其思想和技术遗产散布在计算机科学技术的众多领域。刚开始学习编程的人们就应该接触到结构化编程的基本思想,在专业学习的早期,还会遇到查找图中最短路径的Dijkstra算法。如果学习并发程序技术,那里更是随处散布着Dijkstra的思想和技术贡献。

Dijkstra是20世纪70年代前后程序理论研究领域最重要的开拓者之一,也是那个时代的技术英雄。1968年Dijkstra给CACM的一封信引起轩然大波,激起了结构化编程的倡导者们与维护goto的保守人士的大辩论,最终成就了结构化编程的革命,这是软件开发从个人技艺走向技术和科学的伟大的第一步。Dijkstra与Tony Hoare和Ole-Johan Dahl的专著Structured Programming以其三位作者分别获得图灵奖而永远不可能被超越。其中Dijkstra撰写的“Notes on Structured Programming”提出了软件设计的许多指导原则,其深刻影响覆盖了从基础计算机教育直到复杂软件系统设计的广泛领域。Dijkstra的另一重大贡献是作为最主要的奠基人,参与了并发程序理论和技术基础的开发。他基于自己的并发编程实践提出了许多概念,开发了许多技术。这个领域里的许多术语出自他的思考,包括互斥、同步、竞态条件、死锁、非确定性、自稳定等。他提出了信号量、P/V操作、临界区等概念,是今天所有并发语言和机制的基础。他还留给我们许多并发程序范例,如读者/写者问题、生产者/消费者问题、就餐的哲学家问题等,其中许多就是他上课时留给学生的练习。他开发的THE多道程序系统为操作系统的理论和实现竖起了第一根标杆。Dijkstra在程序正确性领域也做出了极其重要的贡献,这是20世纪70年代之后他最关注的领域,本书就是他一段工作的最重要总结,将在下面详细讨论。如果希望了解Dijkstra的更多贡献,可以参考介绍他的WiKi页和纪念网页

本书原名为A Discipline of Programming,是Dijkstra有关程序理论和编程技术的最重要著作。本书是一本非常独特的编程技术专著。

首先,常见的编程教科书通常要选一种流行语言作为示例的载体,而本书却没用任何可以由计算机执行的语言,所有示例程序都没运行过,但它们的正确性却有保证。作者也没采用“伪代码”,因为伪代码会带来不可避免的歧义性,也无法作为严格的形式化推理的基础。书中的程序采用作者自己设计的一种小语言描述,该语言反映了顺序(非并行)编程语言的最本质性质,还有许多重要特性将在下面讨论。

其次,书中给出了一大批编程实例,采用的方式与其他书籍大相径庭。作者在给出要解决问题的描述之后,总是非常详尽地展示了从问题出发,通过细致的分析思考,逐步深入工作,最后做出所需程序的整个过程。通过这种过程,作者反复展示了在编程中应该怎样思考问题,提出合适的概念,规划处理流程,通过自上而下的设计和开发逐步做出程序框架,分析、解决遇到的具体问题,填充各部分细节,直至做出完整的程序。作者特别提出了“关注点分离”的重要性,强调在一个阶段解决一个问题。在一些复杂程序的开发完成后,还给出了细致的回顾性分析。作者在书中特别注意开发过程的真实性,并不回避提出过的错误概念和走过的弯路。在其他编程著作中,很难看到这种真实的实践。

虽然上面两点已明显表现出本书的与众不同,但它们还不是本书最重要的特点。Dijsktra在本书中最重要的关注点是程序正确性,是关于程序及其意义的“数学推导”和“证明”。作者在前言中写到,我们的目标应该是“做出高度可信的程序,而不仅是……一些胡乱涂抹出来的,……,随时准备被第一个反例推翻的程序文本”。他认为编程工作的目标应该是直接得到正确程序,而不是得到一些“大致能用”的代码。令人遗憾的是,目前的编程工作都并不如作者所愿,人们在开发中反复测试开发的半成品或成品,找出其中缺陷并予以更正,直至其作品或工作过程满足了某些外在“评价标准”,或由于时间、金钱、人力限制而不得不强行结束。到了工作完成时,开发者们也不敢断定给出的就是所需要的“那个”程序。

有关如何开发出正确的程序,书中强调了许多方面的问题。首先是大家熟悉的问题分析,需要在着手编程前把问题弄清楚,做出严格定义,这件事怎么强调都不过分。这件事不需要过多讨论,书中有许多具体示例可供参考。更重要的是,Dijkstra认为保证程序正确的主要武器是数学意义上的严格描述和推导。他在本书中给出了一大批示例,展示了严格推导在编程领域里的威力。Dijkstra认为程序语言(无论哪种语言)本身就是一种形式化的严格定义的描述形式,用它们写出的程序具有确切的语义。用具体计算机运行程序,就是实现其语义,但程序的语义并不依赖于运行它的计算机,可以独立地考虑和表达。从这种认识出发,Dijkstra基于状态和断言的概念提出了最弱前条件的思想,用谓词转换器作为程序语义的落脚点。由于常规语言不能完美地支持这种想法,他自己开发了一种语言,其中最重要的新概念是卫式命令,选择和重复结构都基于卫式命令定义。Dijkstra用实例展示了通过严格推导,直接开发出正确程序的过程,展示了不变式、最弱前条件、谓词转换器等重要概念和严格的逻辑推理怎样在程序开发中发挥作用,帮助开发者(这里的实践者是Dijkstra本人)理清程序的线索,逐步推导出正确的程序。作者提出的最弱前条件、谓词转换器、非确定性等概念,对程序理论和实践的发展都产生了重要影响。

当然,并不是每个人都赞同Dijkstra的想法,即使在未来世界中,也未必所有程序都采用他的理想主义的方式开发。对于数学和逻辑究竟能在编程世界里起多大作用,怀疑者们还在不断地提出质疑,而信仰此道的研究者们也一直在努力工作。可以看到,有关领域的研究取得了许多成果,这些成果正在不断被纳入越来越多的重要软件公司的开发过程,变成流行软件工具的有机组成部分。另一方面,在流行的专业编程书籍中,我们也越来越多地看到有关状态、断言、前后条件、不变式、基于协约的编程等内容的讨论。这些趋势说明,编程作为一种复杂的智力劳动,由于其工作成果将变成当前和未来的工业化、信息化社会中所有基础设施中最关键的支柱,人们必将越来越强烈地关注其产品的正确性和可信任。本书作者在三十多年前的呼喊并没有过时,也不会被遗忘,他提出的想法和技术在未来软件开发中必定会起到越来越重要的作用。原因无二,正如作者在另一处所言:“我早已对计算领域的实践活动有个总结:在那里乱搞的自由度太大,因此,数学的优美绝不是可有可无的奢侈,它关系到生命和死亡”。

本书出版于1976年,20世纪80年代曾被影印并在国内计算机科学界流传,当时书名被译为《程序设计训练》,但很奇怪的是,这本书没有出版过中文译本。20世纪90年代后期,国内计算机领域开始迅猛发展,而这一经典却销声匿迹不为人知,确实很令人遗憾。这次电子工业出版社引进本书,是做了一件绝大的好事。我接手时出版社曾计划以《编程的法则》为书名,我对此有疑。Dijkstra在本书最后专门讨论了一个科学(或其他)领域的形成,及其参与者的智力活动的情况和性质。本书序言作者(图灵奖获得者Tony Hoare)将编程与音乐、诗词等领域相提并论,讨论一个领域中的卓越成就者对后人的启迪和引领。作为一种智力活动的学习和实践者,即需要获取他人经验,也需要内省和自我总结,把这种获得说成是学习一些“法则”,当然不妥。作为领域专家的Dijkstra虽然锋芒毕露,但其实也是一个谦虚的人。原书名用不定冠词“A”开头,表示这只是他认为的在编程领域里有道理的一套智力修炼方法,未必就是终极和唯一的“那一套”。由于以《编程的一种修炼》作为中文书名很别扭,我选了目前这个名字,还好,它也没有强加于人的意味。

翻译本书,就像是在倾听作者缓缓道出的深邃思考,非常有趣,不断地受到启发(虽然我原来已经看过几遍),但也非常累。想把这本书翻译好,确实很困难,术语是最简单的问题(但也颇费琢磨),更重要的是既要准确反映原文的字面意思,还要尽可能反映作者的意图和想法。在此基础上还要尽量符合汉语的习惯,使语言流畅容易理解。要把本书译到满意,我觉得至少还需要一两年时间。但是出版社不能等,因此,我只能把目前的版本呈献给读者。我当然要对书中所有的缺陷负责,并对它们的存在表示歉意。我在这里为本书建一个专门页面,做些后续的弥补工作。最后我要衷心感谢出版社的编辑,他们通过认真工作找出了译文里的一些错误。

裘宗燕
北京大学数学学院信息科学系


2016.11