Erlang之父Joe Armstrong访谈:程序调试与啤酒
以啤酒收取程序调试报酬
Seibel:你是如何开始学习编程的?是从什么时候开始的?
Armstrong:是从中学时开始的。我出生于1950年,上中学那会儿还没有几台计算机。到了中学最后一年,那年我应该是17岁,我们当地的议会得到一台大型计算机,好像是IBM的。我们可以在上面写Fortran程序。通常,我们在编码纸上写好程序,然后发出去。一个星期后,等编码纸和穿孔卡拿回来的时候还必须确认一下。但是制作穿孔卡的人总会出点错,所以可能要反复1~2次才能弄好。最后这些穿孔卡就可以送到计算机中心了。
卡片进入计算机中心后会再拿回来,因为Fortran编译器会在程序中出现第一个句法错误的地方停下来,后面的程序就都不处理了。你的第一个程序似乎需要3个月才能跑通。我认识到,不能每次只送一个程序,应当并行地开发多个单一子例程并且一次都送去。我记得写过一个显示国际象棋棋盘的小程序,用打印机绘制出来。但是因为中间等待的时间太烦人了,我不得不把所有的子例程都当做并行的任务一次写完。
Seibel:你学的是物理学,是从什么时候开始转向编程的?
Armstrong:嗯,有一些本科生的课程需要编写程序,而我又特别喜欢编程。我还非常善于调试程序。如果别人程序出了问题,我就会去调试别人的程序。标准调试的开价是一杯啤酒。也可能提价,还有两杯啤酒、三杯啤酒的问题。
Seibel:在给他们调试程序时,是以他们必须给你买多少杯啤酒而论的,对吗?
Armstrong:对,等我修复了程序时他们要给我买啤酒。我在读程序的时候总是在想:“他们为什么要这样写程序呢,太复杂了。”我会重新编写并简化程序。看到人们编写复杂的代码我感到很吃惊。有些问题用几行代码就能解决,但是他们要写上几十行。我有点好奇,他们为什么看不到简单的方法呢。而我就颇为擅长采取简单的方法。
我真正开始编程是拿到第一个学位并打算读博士学位的时候。我开始读高能物理博士学位并加入了那里的气泡室小组,他们有一台计算机。那是一台DDP-516,是Honeywell公司的。我可以独自一人使用它。它是穿孔卡式的,但是可以在上面直接运行程序,只要把穿孔卡放进去,按一下按钮,答案刷地一下就出来了。我特别喜欢那台计算机。我在上面编写了一个小象棋程序。
那时的实际磁心存储器是由妇女编织而成的,能够看到磁心和一块块的小磁铁和穿进穿出的线路。它的价格高得惊人,有一个大约10MB的磁盘驱动器,上面有20个小底板,大约15公斤重。它还配了一个电传文本的界面,可以在上面输入程序。
后来又出现了“玻璃电传打字终端”,那是最早的视频显示器设备,可以在上面输入并编辑程序。我觉得这太神奇了,再也不需要穿孔卡了。我记得当时和计算机管理员说:“要我说,将来有一天人人都会有这样一套机器。”他说道:“我看你疯了,Joe,你真是疯了!”“为什么不可能呢?”“这些东西贵得离谱。”
正是从那时我真正开始学习编程了。当时我的导师对我说:“你不应该再读物理学博士了,改行吧。你热爱计算机,应当搞计算机。”我说道:“不,不,不。我不能半途而废。”但实际上他的话是对的。
不同寻常的工作经历
Seibel:那你拿到博士学位了吗?
Armstrong:没有。我没钱了,所以没有读完。我后来去了爱丁堡大学。此前在读物理的时候我们常常到物理系图书馆去学习。在图书馆的角落里有一些计算机科学书籍。有一些棕色封底的杂志叫做《机器智能》,一共有4期,是爱丁堡大学的机器智能系编辑出版的。我学的是物理学,但我却渴望阅读这些杂志,并且在想:“真是太有趣了。”DonaldMichie那时担任爱丁堡大学机器智能系的主任,我给他写了封信,说我对这种东西非常感兴趣,问他那里有没有工作可做。他给我回了信,说目前还没有,不过无论如何,他很想和我见一面,看看我是什么样的人。
几个月后我接到一个电话,也可能是一封信,是Michie的。他说:“我周二去伦敦,我们见一面如何?我要乘火车回爱丁堡,你能来车站吗?”我去了车站,见到Michie,他说:“嗯,不能在这儿面试—我们去找个酒吧。”于是我们到一家酒吧聊了聊。过了没多久又收到他的一封信,说:“在爱丁堡大学有一份研究工作,你申请一下吧。”于是我成了DonaldMichie的研究助理并去了爱丁堡大学。我就这样从物理学转到了计算机。
Michie在二战期间曾经和图灵在布莱切利公园(BletchleyPark)(编者注:二战爆发前,英国在距离伦敦不远的布莱切利公园设置了国家密码破译机构,许多破译员在那里工作,破解德国电报密码)一起工作过,拿到了图灵所有的论文。我在图灵图书馆有一张书桌,周围也全都是图灵的论文。我在爱丁堡大学待了一年。此后由于数学家JamesLighthill的原因,爱丁堡大学都有点维持不下去了。Lighthill受雇于政府,前往爱丁堡大学调查人工智能。他回去后说道:“那个地方什么有商业价值的东西也弄不出来。”
说得就像一个巨大的儿童游戏区。我是英国机器人学会的创始成员,我们都认为这个工作意义重大。但是拨款机构却说:“机器人!这是什么东西!我们不打算在这上面投入资金了。”我记得那是1972年前后,所有的资金来源都枯竭了,大家都说:“嗯,在这里度过的时光非常美好,但现在最好还是找点别的事情做吧。”
于是我又回去从事物理学工作了。我到了瑞典,在EISCAT科学协会得到一份物理学程序员的工作。我的上司来自IBM,年纪比我大,他想要上头给出一份规格说明书,这样他就可以拿去实行。我们曾经讨论过这个问题。他说:“如果没有任务说明,也没有规格说明,这样的工作太糟糕了。”我说:“嗯,如果没有任务说明,那才是一个好任务。因为你可以按照自己喜欢的方式来完成。”一年后我的上司离职了,我接替了他的工作,担任首席设计师。
我为他们设计了一个系统,可以称为应用操作系统,那是一个在普通操作系统上运行的系统。那个时候计算机的价格已经比较合理了。我们有一些NORD-10计算机,是挪威制造的—我觉得他们这种型号的计算机想要进入PDP-11的市场。
我在那里工作了将近4年。接着在瑞典空间研究中心得到一份工作,构建了另外一个应用操作系统,用于控制瑞典发射的名为“海盗”的第一颗卫星。那是一个有趣的项目,不过我忘了那台计算机的名字了,只记得它克隆的是Amdahl公司的计算机。那上面还只有行编辑器,没有全屏幕编辑器。所有的程序都只能放到一个目录下面。文件名是10个字母,扩展名是3个字母。还有一个Fortran编译器或汇编语言编译器,全部东西就是这些了。
有趣的是,现在回头想想,我不认为当今这些小玩意会让你的生产率更高。比如说分层文件系统,它怎么可能让生产率更高呢?很多程序开发方式是在脑海中形成的。我认为在那些简单的系统上工作可以强制你规范地进行思考。如果没有目录系统,就只能把所有的文件都放到一个目录下面,你只能变得相当规范。如果没有修订控制系统,你也只能变得相当规范。如果自己做的事情能够规范起来,那我觉得分层文件系统和修订控制系统也就没什么可取之处了。它们解决的问题并不能从本质上解决你的问题。如果多人一起工作,它们可能会让事情容易一些。但对个人来说,我看不出来有什么差别。
另外,我觉得我们现在因为选择过多而不堪重负。我的意思是,那时候我只能使用Fortran。甚至连Shell脚本也没有。只有可以运行程序的批处理文件,编译器,还有就是Fortran。如果确实需要的话,还可能有汇编语言编译器。不需要痛苦地做出选择。今天年轻的程序员肯定会感到很不舒服,面对20种编程语言和几十种框架,该如何选择,真是无所适从。我们那时没有这些难以选择的地方。只要开始做就行了,因为使用什么语言、什么工具都已经是定下来的。不需要考虑该做些什么,只管做就行了。
打开黑盒的重要性
Seibel:另外一个差别是现在也无法彻底了解整个系统了。也就是说不仅仅是要做出很多选择,而且在选择要使用哪些黑盒的时候,还不一定完全理解黑盒的工作方式。
Armstrong:是啊,如果这些大黑盒不能正常工作,必须做出修改,我觉得自己把所有的内容都从头开始编写一次会更容易些。做不到软件复用,真是太糟糕了。
Seibel:但是如果把所有这些黑盒都打开,看看里面有什么,看看它们的工作方式,再确定如何对它们做一点改造来满足自己的需要。你觉得这样做确实是可行的吗?
Armstrong:这些年我犯了一些人们常犯的错误,那就是没有打开黑盒。有时候想一想,觉得这个黑盒无法理解,难度太大,所以不想打开它。我曾经打开过1~2个黑盒。有一次我需要做一个窗口系统,为Erlang做一个图形系统,我在想:“嗯,就在XWindows上运行吧。”XWindows是什么呢?它是一个套接字,上面跑着协议。只要打开套接字,往里面注入这些消息就可以了。为什么要用库呢?Erlang是基于消息的。整体指导思想是向其他东西发出消息,让它们执行操作。嗯,XWindows中的指导思想则是,有一个窗口,向窗口发送消息,再由窗口执行操作。如果在窗口中执行操作,它会把消息回送给你。这非常像Erlang。但是XWindows的编程方式是运用回调库—如果出现了这个情况就调用这个函数。这不是Erlang的思考方式。Erlang的思考方式是,给某个东西发送消息,让它做一些事情。所以,等一下,把其中的库去掉吧,直接和套接字对话。
猜猜结果会怎么样?非常简单。X协议收到了一些消息,我不知道具体是多少条,也许是100条、80条,大致就是这么多。但实际上只需要其中的20条就能完成有用的工作了。把这20条消息映射到Erlang术语上,变个小魔术,然后可以向窗口直接发送消息,它们就开始执行动作了。这样做的效率也很高。但界面不是很好,因为我没有把太多的精力用到图形和艺术标准上。如果为了让界面再美观一些,要做的工作还很多。但是不管怎么说,实际上并不难。
另外一个例子是我做的排版系统,我打开的抽象边界是PostScript。到了边界的地方你会想:“我不想越过这个边界。”因为你会认为边界里面的东西极其复杂。但是我再次发现,它实际上是很简单的。那是一种编程语言,一种不错的编程语言。抽象边界很容易穿越,而一旦穿越,会有很多收益。
在出版我那本Erlang编程书时,出版社说:“我们有画图工具。”但是画图工具真的很难精确地对准箭头,所以我不喜欢那些工具。而且画图的时候手也很难受。我想:“编写一个生成PostScript的程序,然后在‘这里画个圆圈、那里画个箭头’,让程序正常运转起来,这样一比,编程花的时间并不长。”编写程序需要几个小时。以所见即所得的方式画图也需要这么长时间。只是自己编写程序还有两个好处。你的手不会难受,而且即使把图形放大一万倍,看到的箭头也是对得整整齐齐的。
我并不是说刚入行的程序员应当把所有这些抽象的东西都打开。我的意思是,一定要考虑是否可以打开它们。不要完全放弃这个想法。看看直接到达的途径是不是比包装后的途径要快一些,这是值得一看的。一般来说,如果购买软件或是使用其他人的软件,一定要充分考虑还需要花很长时间来加工这套软件,因为它和你想要的不完全一样。软件的执行方式有微妙的差别,而这个差别可能需要很长时间来解决。
编程这些年的变化
Seibel:同刚开始编程时相比,你在看待该如何编程的问题上最大的变化是什么?
Armstrong:我认为编程方式中的最大变化与硬件无关。显然,现在的计算机速度要快得多,功能要强大得多,但是人的大脑比最好的软件工具还要强大一百万倍。我在编写程序的时候,几天之后会突然说:“程序中有一个错误—如果这样、那样、那样、这样的话,程序就要崩溃了。”然后我去看了代码,确实如此。此前一点征兆也没有。你能告诉我哪一个开发系统能够做到这一点吗?作为一个程序员,我所发生的变化是内心思想的变化。
我认为在经过多年的编程之后会有两个变化。一个变化是,在年轻的时候,我会不停地写程序,直到完成。当程序完成后,我就不再管它了。程序写好了,完工了。然后我会突然领悟:“啊!搞错了!真是笨蛋!”我会重新编写程序,后来再次发现:“噢,程序是错的。”于是又重新编写。
我记得当时有这样一个想法:“先不要动手写代码,把这些东西都想好,这样做不是很好吗?”如果我不写代码就能获得那番领悟,不是很好吗?我认为现在可以做到这一点了。那20年可以算作是学习如何编程的时期。现在知道该如何编程了。我以前通过实验来学习编程。现在我知道该如何编程了,不需要再做实验了。
偶尔,我也得做一些很小的实验,比如编写一些非常小的程序来回答某个问题。我会把事情想清楚,等到开始编程的时候,这些程序就可以或多或少地像我预计的那样运行起来了,因为之前我已经想清楚了。这也意味着要花很长时间。编写程序、有所醒悟、重新编写。这样可能需要花上一年的时间来写程序。所以我现在可能不这样做,而是先思考上一年。我不会再做那种简单的输入工作。
这是第一个变化。出现的第二个变化是直觉。在年轻的时候,我会通宵地写程序,干到凌晨4点钟,精疲力尽,那是男子汉气概的编程,一个小时接着一个小时,不停地编写代码。即使情况不好我也坚持不懈,总要让代码能够跑起来。即使没有直觉,我也要继续编程。
我得到的教训是,在疲惫的时候编写的程序都是垃圾,第二天就要把它们都扔掉了。20年前,就算强烈地感到事情不对劲、代码中有错误时,我也会继续编程。这些年来我注意到,真正好的代码是我完全进入状态的时候编写的,时间不知不觉地过了,而我甚至没有在考虑程序,只是很放松地坐在那里,输入这些东西,看着自己输入的东西出现在屏幕上。这样的代码会很不错。如果你不能集中注意力,弄出来的东西会说:“不行,不行,这儿错了,那儿也错了。”可我在多年前并没有注意到这一点。写出来的代码都被扔掉了。现在,如果觉得不行,我就不再编程了。“不能再写了。”这是我根据经验得到的,停下来,不要再写代码了。不要再处理这个问题了。干点别的。
我在上学的时候很擅长数学之类的课程,所以在想:“噢,我是一个按照逻辑思考的人。”但是我参加心理测试时,在直觉上得了高分,而逻辑思考方面的分数却有点低。不是很低,我还是可以做数学这类的题目,我相当擅长。但正是因为我擅长数学,所以我过去认为科学是关于逻辑和数学的。我现在就不会这样说了。我要说科学也有很多直觉,根据直觉能够知道什么是正确的。
Seibel:你现在在编码之前会花更长的时间思考,那么在思考阶段会做些什么呢?
Armstrong:噢,我会记些笔记,我不仅仅是在思考。在纸上随便写点什么。我可能不会写很多代码。如果你密切注意我的活动,会发现我大部分时间都在思考,偶尔写点什么。另外一件对解决问题非常重要的事情是问问我的同事:“你将如何解决这个问题?”你找到他们,说:“我不知道应当采取这种方式还是那种方式。必须在A和B之间做出选择。”然后你向他们描述A和B,等讲到一半的时候,你会说:“啊,是B。谢谢你们。非常感谢。”这样的事情发生过很多次。