译者 Sedgewick
Alfred Aho
计算机科学家、编译器专家Alfred V. Aho一直紧盯计算机科学研究前沿。Aho教授一直致力于编程语言开发,曾任贝尔实验室计算机科学研究中心副主任,现为哥伦比亚大学Lawrence Gussman 计算机科学系教授。
Aho教授不仅是“龙书”系列的作者之一,而且在上世纪70年代同Brain Kernighan 和Peter Weinberger一起开发了模式匹配语言AWK。
近日,《计算机世界》有幸邀请到Aho教授谈一谈AWK的开发。
问:您为什么要开发AWK语言?
和大部分语言一样,AWK是应实际需要而生的。上世纪80年代初,我还是贝尔实验室的研究员。那时我需要追踪经费预算。同时因为我在临近的一所大学兼职,追踪学生的成绩也成了一件棘手的事情。
我想要一种小巧的语言,能让我只写一两行代码就完成这些工作。碰巧Brian Kernighan也有这种需求,于是我俩一起开发了一个专门针对简易数据处理的模式匹配语言。
GREP对我们的影响很大,它是UNIX下一个很流行的字串匹配工具。GREP也是我们研究中心开发的。GREP可以根据某个正则表达式查找文本文件中特定的行,然后输出它们。
我们想进一步扩展它,使得数字也能向字串那样处理。我们还想在打印之外提供一些计算功能。
开发AWK仅仅是用来满足我们,或是那些对计算机不是很懂的人,处理常规数据的需要。它采取“匹配模式——执行动作”的方式工作。
问:在你们开发AWK时有没有哪种程序或是语言已经具备了这些功能?
我们最初是以GREP为原型(开发AWK的)。但是GREP在“模式——动作”处理上有一些局限,所以我们想扩展它。当时,我还在研究字串匹配算法和编译器里的上下文无关文法,自觉不自觉地借鉴了一些LEX和YACC(构造编译器的工具)里的东西。
LEX用于词法分析,而YACC用于语法分析。它俩都是构造编译器的重要工具,当时在贝尔实验室很流行。后来流传开来,用来开发了很多小语言。Brian Kernighan当时用它们来开发数学排版和图形处理语言。
LEX用来分拣输入文本中的词法单元(词元)。词元是一串可以构成逻辑含义的字符,比如,编程语言中的关键字“then”就是一个词元。我们对字母‘t’不感兴趣,对‘h’也不感兴趣,我们感兴趣的是‘then’这个组合。编译器的第一个部分就是词法处理单元,它读入源程序,分析出其中的词元。
AWK受这种词法分析方式的影响(很大),但AWK的定位是数据处理,而且对用户的计算机背景要求很少。
问:您能简短地向《计算机世界》的读者们介绍一下AWK语言吗?
AWK是一门处理文本文件的语言。它把文件看作一串记录(record),缺省情况下一行即为一个记录。每一行又被拆成若干域(field)。我们可以把一行中的第一个词看作第一域,第二个词看作第二域,以此类推。一个AWK程序就是一连串“模式——动作”语句。AWK一次读入一行,然后对照程序中的各个模式进行扫描。一旦匹配成功就执行相应的操作(action)。
举个例可能更清楚一些。假设我们有一个文件,它的每一行都是一个名字后跟一个电话号码。我们假设其中一行为“Pope 15193741273”。AWK语言把第一域记作$1,第二域记作$2,⋯⋯。现在我们想查Pope的电话号码,只需一行AWK语句:$1 == "Pope" { print $2 }
这条语句的意思是:若我们找到一行,其第一域为Pope,则输出其第二域(即电话号码)。现在你已经算是AWK程序员了^_^
AWK程序一般由一组“模式——动作”语句构成。模式可以是字串或数字的真假判断;动作是一组类似C语言的语句。
AWK随着成为UNIX的标配而流行起来。
问:在AWK的开发过程中,您最得意的是什么?
AWK是由Brian Kernighan、Peter Weinberger和我三个人开发的。那时,Peter Weinberger很好奇Brian和我整天在忙什么。我们写好了AWK的语法规范,但缺少一个完整的运行环境。Weinberger跑来对我们说“这看起来很像我写过的一个语言”,然后就在一个星期内写好了AWK的运行环境。我们用这个原始版本来处理我们感兴趣的数据,很称手。更重要的是,它为AWK提供了一个可以不断扩展的平台。
对我来说,最重要的是这个项目让我了解了Kernighan和Weinberger是怎么考虑语言设计的——这真是一次很受益的合作!有了这个灵巧的编译器构造工具,我们就可以完全掌控我们的开发了。我们很快加入了一些新的语法来改进AWK。整整一年,我们都在激烈地讨论哪些特性应该加进AWK,哪些应该丢弃。
语言设计是一项非常随性的活动,每个设计者都会把他们需要的特性加入到语言之中,这些特性或者来自他们需要解决的问题,或者来自他们解决问题的方式。在开发AWK的过程中,我得到了许多乐趣,而和Kernighan、Weinberger他们共事是我的职业生涯中最刺激的事情。我可不想和他们那样的设计者竞争。他们的编程能力无与伦比。
说来也有意思,最开始我们并没有想到,除我们三个以外还会有人用它。但很快我们发现,很多人有数据处理的需求,而这正是AWK所擅长的。人们不愿写几百行的C程序来做数据处理,而同样的工作只需几行AWK代码。于是越来越多的人开始使用AWK。
很多年后,AWK仍然是UNIX下很常用的一个命令。时至今日,即使已经出现了一大批类似的语言,但AWK仍然常年保持在编程语言流行排行榜上25至30名的样子。而这一切都起于我们仨为了满足自己的需要开发的一个小工具。
问:AWK如此流行,您有何感触?
我很高兴有人喜欢AWK。AWK不仅吸引了很多人使用它,后来很多语言的设计者也借鉴了它的工作方式。
在AWK开发出来10年后,Larry Wall开发了一门叫Perl的语言,借鉴了AWK和其他一些UNIX工具的特性。Perl现在是世界上最流行的语言之一。所以不光是它刚出现的时候受欢迎,它也影响了很多新生语言。
问:您刚才提到AWK影响了很多语言,您认为这是为什么?
最初让AWK得以流行是因为它的简洁和它的定位。它有一个很简单的编程模型。它这种“识别模式——执行动作”的编程方式很容易理解。我们还在AWK中添加了对管道的支持。AWK里的动作其实就是一些简单的C程序。你既可以写下像{ print $2 } 这样简单的动作,也可以为某个模式写一个复杂得多的类C程序。甚至华尔街的一些金融机构都用AWK来做账,因为它处理起数据来真的很简单。
AWK的学习曲线很平缓,很多人都是从AWK开始接触编程这行的。即使是今天,仍有很多人还在使用AWK,他们说像Perl这样的语言变得太复杂了。
AWK的另一个优势在于它很稳定。自上世纪80年代中期以后,我们就没有改动过它了。所以也有很多人将AWK移植到不同的平台(比如Windows)上。
问:A、W、K这个顺序最初是怎么定的?
这其实不是由我们定的。研究中心的同事看到我们仨挤在一个屋里,就推门喊到“AWK! AWK!”。我们觉得不错,就叫它AWK了。我们出版那本《AWK编程语言》时还专门在封面里加了一只海雀(译注:AUK,音同AWK)。
问:您开发AWK时收获哪些受益至今的经验?
我的研究方向包括算法和程序语言。很多人知道我是因为AWK。很多人在学术论文里引用我们的算法(已经在很多工具里实现了),但很少有人因为这个知道我。在我们开发AWK时借鉴了很多高效的字串匹配算法。UNIX的很多工具,包括EGREP和FGREP这两个我研究字串匹配时写的小程序,也用到了这些算法。
AWK是理论与实践结合的典范。最好的工程实践往往是建立在科学的基础上。我们在AWK中引入了富于表达的记法和高效的算法。实际中,它们的效率也很高。
和聪明人共事你会获得智慧。Brian Kernighan就是这样的聪明人,一个程序语言设计大师。他的心得就是保持简洁,简洁的语言易于理解,也易于使用。我想,这就是对所有语言设计者最好的忠告。
问:AWK开发出来这么多年,您有没有遇到过什么惊喜?
有次星期一一上班,我发现有个人在我办公室。他是贝尔实验室微电子产品部门的,他说他用几千行AWK写了一个计算机辅助设计系统。我当时就惊呆了。我原以为没人会写超过一千行的AWK。但他用AWK写了一个很强大的CAD开发系统。他说用AWK来开发很快,很灵巧。最让我惊奇的是,我们从没想到会出现这么多用AWK写的应用。可能这是一个好工具的标志,就像起子不仅仅只能拧螺丝一样。
问:您今天还在用AWK吗?
我现在还在用AWK处理数据,它很好用。举个例子,我写论文、写报告时会用它来做图片和示例的自动编号,这需要用到它的关联数组。比如说,它可以把“图片 AWK程序”这样的注释转换为“图片 1.1”。我写了两行AWK来实现这个功能。我曾见过一片论文用来1000行C代码写了一个功能还不及我那两行AWK的程序。用过AWK,你就会对它在表达上的简洁干练印象深刻。
问:AWK之父的声誉对您的职业生涯有什么影响吗?
我说过,很多人知道我是因为AWK,但在计算机科学这个研究圈子里人们对我在理论方面的工作更熟悉。所以最初我只是把开发AWK视为一种实践,而不是正儿八经的研究。但开发AWK的这段经历,对我日后教授编程语言、编译器、软件工程这些课程还是产生了很大的影响。
我注意到,人们知道某些科学家不是因为他们的研究成功,反而是因为他们发明的某个工具。比如,世界上最著名的计算机科学家——Don Knuth,计算机算法领域的奠基人。他发明了一种文字排版的语言,Tex。文字排版不是他研究的主要方向,但Tex却得到很多非计算机专业的科学家的广泛使用。而Knuth之所以要发明一套数学排版系统只是因为他希望自己的论文和著作好看一些。
很多计算机科学家在研究之外发明了很多好用的编程语言。另一个著名的例子就是Bjarne Stroustrup开发C++最初只是为了写一个网络模拟器。
问:如果现在重新开发AWK,您会做出哪些改变?
我会在开发之初就制定严格的测试。我们最初把AWK定位为一种用过即扔的语言,所以在最初的实现中没有做严格的质量控制。
我之前提到过一个用AWK写了CAD系统的家伙。他最初来见我的原因就是为了报告一个AWK编译器里的bug。他很生气地对我说,他浪费了三周时间来查错,却发现原来是编译器的问题!我和Brian Kernighan商定,一定要引入质量控制。所以我们为所有的特性制定了一套严格的回归测试。打那以后,每次我们要给AWK添加什么特性总会先写测试。
多年来,我一直在哥伦比亚大学教程序语言和编译。这门课有一个工程实践,学生们四个或五个一组用一整学期来设计他们自己的小型语言,还要做出一个编译器。
上这门课的学生之前都没有深入了解过编译器,但这些年来从没有一个组没能完成任务。这都要归功于我和Kernighan、Weinberger他们一起在开发AWK时积攒的经验。除了学习程序语言和编译器设计的原则,学生们还能(通过工程实践)了解到实际中的软件开发。每个学生都应该从一开始就养成严格测试的习惯。学生们还能学到工程管理、团队合作、口头交流和文档撰写方面的技巧。所以从这个角度讲,AWK真的对我教程序语言、编译和软件开发都有很深的影响。
P.S. 翻译于我果然很难,总有茶壶装汤圆的感觉。
P.P.S. 我对AWK感兴趣最初是因为读了这篇文章,为什么你应该学点Awk(附指南及示范) 。