为什么编程是困难的

本文是翻译,版权归原作者所有


许多年前我认为编程比较容易,随着时间的流逝,我意识到编程并不容易。这是因为我对编程是什么和程序员应该做什么有了缓慢的认知改变。

起初我认为编程仅仅是告诉电脑做什么,这部分编程工作相对容易。经过20多年的实践,我估计这部分编程工作是相当容易的。

[caption id=”attachment_267” align=”alignnone” width=”551”]编程的定义 编程的定义[/caption]

定义1:程序是把输入转换成输出的东东。

程序员就是写程序的人,编程就是写程序的工作。

让我们根据我对程序的定义增加一些约束。

定义2:程序是根据以下约束,把输入转换成输出的东东:

有了这些附加约束,编程变得相当难了。

对于一个特定问题,某些约束可能就不严格了。

一些经典脚本这样建议自己:

不必维护的程序

我们写程序经常只是为了输出。这样输入和程序本身将来就不必维护,因此不必太优美或说明。

我的Erlang那本书就是一个例子。当书出版后,维护产生这本书的输入和程序就没有必要了。结果看起来不错,但是输入是由大量的XML文件和从来不必维护的小测试程序组成的。

用于重印的、书的勘误表和必要纠正仅仅对输入做了微小改动,这很容易,即使程序的输入没有良好的文档。

程序必须可维护

与上个脚本相反,程序必须是可维护的。程序的输入和程序本身必须是优美的、具备良好的文档。

前几天我和开发web应用程序的电脑顾问聊天。他说,程序的输出只要看起来正确(例如,网站看起来ok,程序好像运行正常),客户就认为项目结束了,项目经理会给他安排下一个项目。

没有时间,也不会理解这一点:在开始下一个项目之前,除了网站看起来ok,背后的代码也应当是干净的、具备文档。项目将来需要维护。

增加编程难度的其他方面

有3点:

让我们看看——这些都是“拖延”(time thieves)。

修复不应当中断的地方

为了解决一个特定问题,我经常不得不使用我以前没有写过、也不真正理解的软件。

最好的情况是,我不得不使用的程序对于用法有精确的说明。但是程序常常没有说明或没有一个正确的说明。

因此当文档说“做XYZ,那么PQR就会出现”,然后你做了“XYZ”,但是“PQR”没有出现,你该怎么办?如果幸运,程序作者在旁边,因此你可以搞定它们。如果不是这样,你试着Google碰碰运气,或去源代码里找答案。

为了修复bug去使用Google是相当令人沮丧的。我Google一会儿,发现一篇文章里写着不幸的人碰到了和我一样的问题。我兴奋起来,我用发抖的手指进入移除魔咒的魔法符,只是……什么也没有。问题依然存在。

为什么方法对别人管用,对我却不起作用。他们是监视我的带有恶意的上帝?或者我正处在物理规律临时改变了的宇宙一角?不,我们两台电脑的初始状态是不同的,因此在一台电脑的一种状态下修复一个bug,不一定会修复处于不同状态的电脑上的bug。

有时候我希望我在用Smalltalk编程,我们都从完全相同的程序映象(program image)开始——Smalltalk程序员一定活在不可能出现上面情况的、某种天堂里,只是有一天他们的程序或许不得不与其他程序对话,那么有趣的事情就会发生了。

修复损坏的地方难上加难,甚至当你移除了这个bug,你仍然不敢肯定它是不是你最后一次修复该问题,或者你做的所有改变带来的网络影响。

顺便说一句,问题是我花费的大部分时间,有60%-70%是在猜测。我又一次花费一周多试着修复一个有问题的LDAP服务器——老板禁止我实现自己的LDAP服务器——用C实现、没有文档,经过与它一周时间的奋斗,我的记忆出现了衰退,忘记了老板说的话,在午饭间隙非常意外地用Erlang从头开始实现了一个服务器。

老实讲,它不是一个功能齐全的LDAP服务器,但是我不需要,因为我仅仅想要一堆能运行的命令,还容易修复。

如今我在实现古老的、任性的协议中找不到特别乐趣了,但是进度的最快方式常常是从头实现它们。

解决问题但不需要学习

我很懒,我是个一无是处的懒鬼。但是当我想把一张图表放进LaTeX时,我不想必须首先阅读一份391页的手册。我知道你会指责我懒惰,道德不健全,我知道我应该首先阅读友好的手册,但是我的文档需要一张图表,花十分钟去阅读391页的手册是不需要的。

解决问题时我追求快速解决问题的方法,但从长期看这是有害的。

需要文档作品。我在TeX/LaTeX、XSLT-FO和我自己的Erlguten之间犹豫不定。

大概每3年我就有强烈的欲望,直接撰写全部的文档做为补充,然而唯一做的事情就是深吸一口气,等到这种感觉消失。

我猜想,当Giambattista Bondoni在1818年创造他的Manuale Tipografico时,不会特别在意排版一页要花数周的时间。但是现在我们有了太多的时间,因为我们让机器做这些单调危险的、我们没有时间正确完成的工作。

我问老板他是否想在下一次演示中需要“好的幻灯片”,他说需要,让我明天之前交给他。这样我没有合适的时间学习Tex(我想在数年完成),没有时间实现我自己的排版语言(花5-10年),没有时间直接补充完成(大概一周)——因此我想我需要PowerPoint。

糟糕的编程环境

如果你已经读到了这里,你会理解我认为的编程是非常非常困难的。这就是为什么工作区被设计成使得编程更加困难的原因。我们有开放规划办公场所,提供了一个嘈杂的环境来打断注意力,移动手机打扰着我们,因特网分散着我们的精力。

幸运的是,我们有不被打扰的场所。睡觉。很多编程问题在你睡觉的时候会得到解决。

有两种方法。首先,你把问题放入大脑,然后你睡觉,第二天醒来后,一些问题就解决了。容易吧。

方法二:你将问题提交到网上,或在起床之前写个tweet,第二天某个人会邮件告诉你解决方法。

成为一名好的程序员需要很长时间,你需要学习很多东西,你需要知道遇到问题时向谁求教。

令人惊奇却真实存在

当我写完这篇文章时,我想检查拼写。emacs的ispell套件模式开始罢工,它找不到aspell,这是我用来检查拼写的程序。

我的emacs拼写检查器已经在这台电脑上忠诚地工作数年了。仅仅在我抱怨花费了半生时间修复不应该出现的问题时,emacs拼写检查器会出错。

我不相信带有恶意的上帝,也不相信写文章的我所在的、客厅沙发左手角落的物理规律有什么不同,虽然有详细的证据支持其对立面。

我找不到我的拼写检查器崩溃的原因,一切都好好的,我没有修改什么。从上次检查了一篇文档的拼写之后,我安装了Erlang的新版本,安装了Julia,写了一些演讲笔记。

幸运的是,11分钟的Google有了结果。如何修复问题的第二个建议管用——我仍然不知道为什么emacs不能找到aspell——生命苦短,无法探究其因。

我想有一些事情是我们永远都不会知道的。

译文:为什么编程是困难的 》| 腊八粥