黑客与画家
黑客与画家
2003年5月
(本文源于在哈佛大学的一次客座讲座,该讲座整合了之前在东北大学的一次演讲。)
当我完成计算机科学研究生学业后,我去艺术学院学习绘画。很多人似乎对感兴趣于计算机的人也会对绘画感兴趣感到惊讶。他们似乎认为黑客和绘画是截然不同的工作类型——黑客工作是冷酷、精确、有条理的,而绘画则是某种原始冲动的狂热表达。
这两种形象都是错误的。黑客和绘画有很多共同之处。事实上,在我认识的所有不同类型的人中,黑客和画家是最相似的。
黑客和画家的共同点是他们都是创造者。与作曲家、建筑师和作家一样,黑客和画家试图做的是创造好东西。他们本身并不是在做研究,尽管在试图创造好东西的过程中他们发现了一些新技术,那就更好了。
我从来不喜欢”计算机科学”这个词。我不喜欢它的主要原因是没有这样的东西。计算机科学是一堆关系不大的领域的拼凑,因历史的偶然而被组合在一起,就像南斯拉夫一样。一端是实际上是数学家的人,但他们称自己做的事情为计算机科学,以便获得DARPA资助。中间是从事类似计算机自然史工作的人——例如研究通过网络路由数据的算法行为。然后在另一端是黑客,他们试图编写有趣的软件,对他们来说,计算机只是表达媒介,就像对建筑师来说是混凝土,对画家来说是颜料一样。这就像是数学家、物理学家和建筑师都必须在同一个系里一样。
有时黑客所做的事情被称为”软件工程”,但这个术语同样具有误导性。优秀的软件设计师并不比建筑师更像工程师。建筑和工程之间的界限并没有明确界定,但它是存在的。它在于做什么和如何做之间:建筑师决定做什么,工程师弄清楚如何做。
做什么和如何做不应过于分离。如果你试图在不知道如何做的情况下决定做什么,那是在自找麻烦。但黑客工作绝不仅仅是决定如何实现某个规范。在最好的情况下,它是创建规范——但事实证明做到这一点的最好方法是实现它。
也许有一天”计算机科学”会像南斯拉夫一样被分解成其组成部分。这可能是件好事。特别是如果这意味着我自己的领域——黑客的独立。
将所有这些不同类型的工作捆绑在一个部门可能在行政上很方便,但在智力上是混乱的。这是我不喜欢”计算机科学”这个名字的另一个原因。可以说,中间的人在做类似实验科学的事情。但两端的人,黑客和数学家,实际上并不是在做科学。
数学家似乎并不为此困扰。他们很高兴地开始证明定理,就像数学系的数学家一样,并且很快就会停止注意到他们工作的建筑外面写着”计算机科学”。但对黑客来说,这个标签是个问题。如果他们所做的事情被称为科学,这让他们觉得他们应该表现得科学。因此,大学和研究实验室里的黑客不做他们真正想做的事情,即设计美丽的软件,而是觉得他们应该写研究论文。
在最好的情况下,论文只是一种形式。黑客编写很酷的软件,然后写一篇关于它的论文,论文就成为了软件所代表成就的代理。但这种不匹配经常导致问题。很容易从创造美丽的东西转向创造丑陋的东西,而这些东西更适合作为研究论文的题材。
不幸的是,美丽的东西并不总是最好的论文主题。首先,研究必须是原创的——正如任何写过博士论文的人所知,确保你在探索未知领域的方法是占据一块没有人想要的地盘。其次,研究必须是实质性的——笨拙的系统会产生更丰富的论文,因为你可以写为了完成工作而必须克服的障碍。没有什么比从错误假设开始更能产生丰富的问题了。大多数人工智能都是这个规则的例子;如果你假设知识可以表示为谓词逻辑表达式的列表,其参数代表抽象概念,你将有很多论文要写关于如何使其工作。正如里奇·里卡多常说的:“露西,你有很多解释要做。”
创造美丽东西的方法往往是对现有事物进行微妙的调整,或者以稍新的方式组合现有的想法。这种工作很难在研究论文中传达。
那么为什么大学和研究实验室继续用出版物来判断黑客呢?原因与”学术能力”用简单的标准化测试衡量,或者程序员的生产力用代码行数衡量是一样的。这些测试很容易应用,没有什么比一个勉强有效的简单测试更诱人的了。
衡量黑客真正试图做的事情,设计美丽的软件,会困难得多。你需要良好的设计感来判断好的设计。人们识别好设计的能力与他们对自己能做到的信心之间没有任何相关性,除了可能是负相关。
唯一的外部测试是时间。随着时间的推移,美丽的东西往往会繁荣,丑陋的东西往往会被抛弃。不幸的是,所涉及的时间可能比人类寿命还长。塞缪尔·约翰逊说,作家的声誉需要一百年才能收敛。你必须等待作家有影响力的朋友死去,然后他们所有的追随者都死去。
我认为黑客只能接受自己声誉中有很大的随机成分。在这方面,他们与其他创造者没有什么不同。事实上,相比之下,他们是幸运的。时尚在黑客中的影响力远不如在绘画中那么大。
有比被人误解你的作品更糟糕的事情。更危险的是你会自己误解你的作品。相关领域是你寻找想法的地方。如果你发现自己身处计算机科学系,自然会有一种诱惑,例如认为黑客是理论计算机科学理论的应用版本。我在研究生院的整个时间里,脑海中总有一种不安的感觉,觉得我应该知道更多理论,而且在期末考试后三周内忘记所有东西是非常疏忽的。
现在我意识到我错了。黑客需要了解计算理论的程度,与画家需要了解颜料化学的程度差不多。你需要知道如何计算时间和空间复杂性以及图灵完备性。你可能还想记住至少状态机的概念,以防你不得不编写解析器或正则表达式库。事实上,画家必须记住的颜料化学知识比这多得多。
我发现,最好的想法来源不是名字中有”计算机”一词的其他领域,而是创造者居住的其他领域。绘画比计算理论是更丰富的想法来源。
例如,我在大学里学到的是,一个人应该在完全接触计算机之前在纸上完整地构思一个程序。我发现我不是这样编程的。我发现我喜欢坐在计算机前编程,而不是在纸上。更糟糕的是,我不是耐心地写出完整的程序并确保它是正确的,而是倾向于只是喷出完全没有希望的代码,然后逐渐把它塑造成形。我学到的是,调试是一种最后阶段,你捕捉打字错误和疏忽。按照我的工作方式,编程似乎就是由调试组成的。
很长时间以来,我对此感觉很糟糕,就像我曾经因为小学时握铅笔的方式和他们教我的不一样而感到难过一样。如果我看过其他创造者,画家或建筑师,我会意识到我所做的事情有一个名字:素描。据我所知,他们在大学教我的编程方法完全是错的。你应该在编写程序时构思程序,就像作家、画家和建筑师所做的那样。
意识到这一点对软件设计有实际意义。这意味着编程语言最重要的特性应该是可塑的。编程语言是用来思考程序的,而不是表达你已经想好的程序。它应该是一支铅笔,而不是一支钢笔。如果人们真的像他们在大学教我的那样写程序,静态类型会是个好主意。但这不是我认识的任何黑客写程序的方式。我们需要一种让我们能够涂鸦、涂抹和弄脏的语言,而不是一种你必须用一杯类型平衡在膝盖上与严格的老婶婶编译器礼貌交谈的语言。
既然我们在讨论静态类型,认同创造者将使我们免于困扰科学的另一个问题:数学嫉妒。科学界的每个人都秘密认为数学家比他们聪明。我认为数学家也相信这一点。无论如何,结果是科学家倾向于使他们的工作看起来尽可能数学化。在像物理学这样的领域,这可能不会造成太大伤害,但离自然科学越远,这个问题就越大。
一页公式看起来非常令人印象深刻。(提示:为了更加令人印象深刻,使用希腊变量。)因此,有很大的诱惑去做你可以正式处理的问题,而不是那些重要的,比如说,重要的问题。
如果黑客认同其他创造者,比如作家和画家,他们就不会感到诱惑去做这种事情。作家和画家不遭受数学嫉妒。他们觉得他们在做完全不相关的事情。我认为黑客也是如此。
如果大学和研究实验室阻止黑客做他们想做的工作,也许他们的位置是在公司。不幸的是,大多数公司也不会让黑客做他们想做的事情。大学和研究实验室强迫黑客成为科学家,公司强迫他们成为工程师。
我自己直到最近才发现这一点。当雅虎收购Viaweb时,他们问我想做什么。我从来不太喜欢商业方面,说我只想黑客。当我到雅虎时,我发现黑客对他们来说意味着实现软件,而不是设计它。程序员被视为技术人员,将产品经理的愿景(如果那算是的话)翻译成代码。
这似乎是大公司的默认计划。他们这样做是因为它减少了结果的标准差。只有一小部分黑客能够真正设计软件,公司经营者很难挑选出这些人。因此,大多数公司不将软件的未来委托给一个才华横溢的黑客,而是设置成由委员会设计,黑客只实现设计。
如果你想赚钱,记住这一点,因为这是创业公司获胜的原因之一。大公司希望减少设计结果的标准差,因为他们想避免灾难。但当你抑制波动时,你既失去了高点,也失去了低点。这对大公司来说不是问题,因为他们不是靠做出伟大的产品获胜的。大公司靠比其他大公司少些糟糕获胜。
所以如果你能找到一种方法与一家大公司进行设计战争,大到其软件是由产品经理设计的,他们将永远无法跟上你。不过,这些机会并不容易找到。很难让大公司参与设计战争,就像很难让城堡内的对手进行肉搏战一样。例如,编写一个比微软Word更好的文字处理器会很容易,但微软在其操作系统垄断的城堡内,即使你做到了,可能甚至不会注意到。
进行设计战争的地方是新市场,在那里还没有人设法建立任何防御工事。在那里,你可以通过大胆的设计方法,以及让同样的人既设计又实现产品而大获全胜。微软自己一开始就是这样做的。苹果也是如此。惠普也是如此。我怀疑几乎所有成功的创业公司都是如此。
所以构建伟大软件的一种方法是创办自己的创业公司。然而,这有两个问题。一是在创业公司,你必须做很多编程以外的事情。在Viaweb,如果我能有四分之一的时间黑客,我就觉得自己很幸运。我在其他四分之三的时间里不得不做的事情从乏味到可怕不等。我对此有一个基准,因为我曾经不得不离开董事会会议去补牙。我记得坐在牙医的椅子上,等待钻头,感觉就像在度假。
创业公司的另一个问题是,赚钱的软件和有趣的软件之间没有太多重叠。编程语言写起来很有趣,微软的第一个产品确实是,但现在没有人会为编程语言付钱。如果你想赚钱,你往往被迫从事对任何人来说都太麻烦而无法免费解决的问题。
所有创造者都面临这个问题。价格由供求关系决定,对有趣工作的需求不如解决个人客户日常问题的需求多。在外百老汇戏剧中表演不如在贸易展上穿着大猩猩服装在别人的展位工作赚钱。写小说不如为垃圾处理器写广告文案赚钱。黑客编程语言不如想办法将某公司的遗留数据库连接到他们的Web服务器赚钱。
我认为这个问题的答案,在软件的情况下,是一个几乎所有创造者都知道的概念:日常工作。这个词始于音乐家,他们晚上表演。更一般地说,这意味着你做一种工作是为了钱,做另一种是为了爱。
几乎所有创造者在职业生涯早期都有日常工作。画家和作家尤其如此。如果你幸运,你可以找到与你真正工作密切相关的日常工作。音乐家似乎经常在唱片店工作。从事某种编程语言或操作系统工作的黑客同样可能能够使用它获得日常工作。[1]
当我说答案是为黑客提供日常工作,并在业余时间从事美丽软件工作时,我并不是在提出一个新想法。这就是开源黑客的全部内容。我要说的是,开源可能是正确的模式,因为它已经被所有其他创造者独立证实。
任何雇主都不愿让黑客从事开源项目,这让我感到惊讶。在Viaweb,我们不愿意雇佣任何不这样做的人。当我们面试程序员时,我们主要关心的是他们在业余时间编写什么样的软件。除非你热爱它,否则你不能真正做好任何事情,如果你热爱黑客,你将不可避免地从事自己的项目。[2]
因为黑客是创造者而不是科学家,寻找隐喻的正确地方不是科学,而是其他类型的创造者。绘画还能教给我们什么关于黑客的知识?
我们可以从绘画的例子中学到的一件事,或者至少确认的是,如何学习黑客。你主要通过做来学习绘画。黑客也是如此。大多数黑客不是通过上大学编程课程来学习黑客的。他们在十三岁时通过编写自己的程序来学习黑客。即使在大学课程中,你也主要通过黑客来学习黑客。[3]
因为画家在他们身后留下了作品的痕迹,你可以看着他们通过做来学习。如果你按时间顺序看一位画家的作品,你会发现每幅画都建立在以前画中学到的东西的基础上。当一幅画中有某个东西效果很好时,你通常可以在一些早期绘画中以较小的形式找到它的版本1。
我认为大多数创造者都是这样工作的。作家和建筑师似乎也是如此。也许黑客应该更像画家,定期从头开始,而不是继续在一个项目上工作多年,并试图将他们以后的想法作为修订纳入其中。
黑客通过做来学习黑客这一事实是黑客与科学不同的另一个标志。科学家不是通过做科学来学习科学,而是通过做实验和解决问题集。科学家开始做的工作是完美的,在这个意义上说,他们只是试图重现别人已经为他们做过的工作。最终,他们达到可以做原创工作的地步。而黑客从一开始就在做原创工作;只是非常糟糕。所以黑客从原创开始,然后变好,科学家从好开始,然后变原创。
创造者学习的另一种方式是通过例子。对画家来说,博物馆是技术参考图书馆。数百年来,复制大师作品一直是画家传统教育的一部分,因为复制迫使你仔细审视绘画的制作方式。
作家也这样做。本杰明·富兰克林通过总结艾迪生和斯蒂尔散文中的观点,然后尝试重现它们来学习写作。雷蒙德·钱德勒对侦探故事做了同样的事情。
同样,黑客可以通过看好的程序来学习编程——不仅看它们做什么,还看源代码。开源运动不太公开的好处之一是它使学习编程变得更容易。当我学习编程时,我们主要依靠书中的例子。当时可用的一大块代码是Unix,但即使这不是开源的。大多数阅读源代码的人是通过约翰·莱昂斯书的非法影印本来阅读的,这本书虽然写于1977年,但直到1996年才被允许出版。
我们可以从绘画中借鉴的另一个例子是绘画是通过渐进改进而创造的。绘画通常从素描开始。逐渐地,细节被填入。但这不仅仅是填入的过程。有时原来的计划被证明是错误的。无数的绘画,当你用X光看时,发现肢体被移动了或面部特征被重新调整了。
这里有一个我们可以从绘画中学习的例子。我认为黑客也应该这样工作。期望程序的规格说明是完美的是不现实的。如果你提前承认这一点,并以允许规格说明在运行中更改的方式编写程序,你会更好。
(大公司的结构使他们很难做到这一点,所以这是创业公司有优势的另一个地方。)
现在大概每个人都知道过早优化的危险。我认为我们应该同样担心过早设计——过早决定程序应该做什么。
正确的工具可以帮助我们避免这种危险。一个好的编程语言应该像油画一样,使你容易改变主意。动态类型在这里是个优势,因为你不必预先承诺特定的数据表示。但我认为灵活性的关键是使语言非常抽象。最容易更改的程序是非常短的程序。这听起来像是一个悖论,但一幅伟大的绘画必须比它必须的要更好。例如,当莱昂纳多在华盛顿国家美术馆画吉内薇拉·德·班奇的肖像时,她在她头后放了一棵杜松树。他在其中仔细地画了每一片叶子。许多画家可能认为,这只是放在背景中框住她头部的东西。没有人会那么仔细地看它。
不是莱昂纳多。他在画的一部分上工作的努力程度完全不取决于他期望任何人看它的程度。他像迈克尔·乔丹。无情。
无情获胜是因为,总的来说,看不见的细节变得可见。当人们走过吉内薇拉·德·班奇的肖像时,他们的注意力常常立即被它吸引,甚至在他们看标签并注意到它说莱昂纳多·达·芬奇之前。所有那些看不见的细节结合在一起产生了一些令人惊叹的东西,就像一千个几乎听不见的声音都在和谐地歌唱。
伟大的软件同样需要对美的狂热奉献。如果你看好的软件内部,你会发现那些永远不应该被看见的部分也是美丽的。我不声称我写伟大的软件,但我知道当涉及到代码时,我的行为方式如果用在日常生活中会让我有资格获得处方药。看到缩进糟糕的代码或使用丑陋变量名的代码会让我发疯。
如果黑客只是一个实现者,将规范变成代码,那么他就可以像挖沟的人一样从一端到另一端完成工作。但如果黑客是创造者,我们必须考虑灵感。
黑客像绘画一样,工作是周期性的。有时你对某个新项目感到兴奋,一天想工作十六个小时。有时似乎没有什么有趣的。
要做好工作,你必须考虑这些周期,因为它们受到你对他们反应的影响。当你在山坡上驾驶手动变速器汽车时,你必须有时松开离合器以避免熄火。松开同样可以防止雄心熄火。在绘画和黑客中,有些任务是令人恐惧的雄心勃勃的,有些则是令人安慰的常规。留一些容易的任务给那些否则会停滞的时刻是个好主意。
在黑客中,这实际上可能意味着保存错误。我喜欢调试:这是黑客像人们认为的那样直截了当的唯一一次。你有一个完全受限的问题,你只需要解决它。你的程序应该做x。相反它做y。它哪里出错了?你知道你最终会赢。这就像刷墙一样放松。
绘画的例子不仅可以教我们如何管理自己的工作,还可以教我们如何一起工作。许多过去的伟大艺术是多人之手的作品,尽管博物馆墙上可能只有一个名字。莱昂纳多是维罗基奥工作室的学徒,画了他的《基督受洗》中的一个天使。这种事情是规则,而不是例外。米开朗基罗因为坚持亲自绘制西斯廷教堂天花板上的所有人物而被认为特别专注。
据我所知,当画家一起在一幅画上工作时,他们从不工作的相同部分。大师画主要人物,助手画其他人物和背景是常见的。但你从来没有一个人在另一个人的作品上绘画。
我认为这是软件协作的正确模式。不要推得太远。当一段代码被三四个不同的人黑客攻击,没有人真正拥有它时,它最终会像一个公共休息室。它往往会感觉荒凉和被遗弃,并积累无用之物。我认为协作的正确方法是将项目分成明确定义的模块,每个模块都有明确的拥有者,它们之间的接口尽可能精心设计,如果可能的话,像编程语言一样明确。
像绘画一样,大多数软件是为人类受众准备的。因此,像画家一样,黑客必须有同理心才能做真正伟大的工作。你必须能够从用户的角度看问题。
当我还是个孩子的时候,我总是被告知要从别人的角度看问题。这在实践中总是意味着做别人想要的事情,而不是我想要的事情。这当然给同理心一个坏名声,我故意不培养它。
哦,我错了。事实证明,从别人的角度看问题实际上是成功的秘密。这不一定意味着自我牺牲。远非如此。理解别人如何看待事物并不意味着你会为他的利益行事;在某些情况下——例如,在战争中——你想做的恰恰相反。[4]
大多数创造者为人类受众制造东西。要吸引受众,你必须理解他们需要什么。例如,几乎所有最伟大的绘画都是人物画,因为人对人感兴趣。
同理心可能是好黑客和伟大黑客之间最重要的区别。一些黑客相当聪明,但当涉及到同理心时,他们实际上是唯我论者。这样的人很难设计伟大的软件[5],因为他们不能从用户的角度看问题。
判断人们同理心好坏的一个方法是看他们向没有技术背景的人解释技术问题的方式。我们可能都认识一些人,尽管在其他方面很聪明,但在这方面糟糕得可笑。如果有人在晚宴上问他们什么是编程语言,他们会说类似”哦,高级语言是编译器用来生成目标代码的输入。“高级语言?编译器?目标代码?显然不知道什么是编程语言的人也不知道这些东西是什么。
软件必须做的一部分是解释自己。所以要写好的软件,你必须理解用户理解得多么少。他们将在没有准备的情况下接近软件,它最好做他们猜测它会做的事情,因为他们不会读手册。在这方面我见过的最好的系统是1985年的原始Macintosh。它做了软件几乎从不做的事情:它就是工作。[6]
源代码也应该解释自己。如果我能让人们记住关于编程的一句引语,那就是《计算机程序的结构和解释》开头的那句。程序应该写给人读,只是顺便给机器执行。你不仅需要为你的用户有同理心,还要为你的读者。这符合你的利益,因为你将是其中之一。许多黑客写了一个程序,六个月后回到它却发现不知道它是如何工作的。我认识几个人在这样的经历之后发誓不再使用Perl。[7]
缺乏同理心与智力相关,以至于在某些地方甚至有成为一种时尚的趋势。但我不认为有任何相关性。你可以在数学和自然科学中做得很好而不必学习同理心,这些领域的人往往很聪明,所以这两种品质变得相关起来。但也有很多愚蠢的人不善于同理心。只要听听脱口秀节目打电话提问的人就知道了。他们用如此拐弯抹角的方式问他们的问题,以至于主持人常常不得不为他们重新表述问题。
那么,如果黑客像绘画和写作一样工作,它有那么酷吗?毕竟,你只有一次生命。你不妨花时间做一些伟大的事情。
不幸的是,这个问题很难回答。声望总是有很大的时间滞后。这就像来自遥远恒星的光。绘画现在有声望是因为人们五百年前所做的伟大工作。当时,没有人认为这些绘画像我们今天认为的那么重要。在那个时候,人们会觉得乌尔比诺公爵费德里科·达·蒙特费尔特罗有一天主要因皮耶罗·德拉·弗朗切斯卡绘画中奇怪的鼻子而被人认识,这会显得很奇怪。
所以虽然我承认黑客现在似乎不像绘画那么酷,但我们应该记住,绘画在其全盛时期也不像现在这么酷。
我们可以有一定信心地说这些是黑客的全盛时期。在大多数领域,伟大的工作都是早期完成的。1430年到1500年间制作的绘画仍然无与伦比。莎士比亚出现在专业戏剧诞生之时,将媒介推得如此之远,以至于此后的每个剧作家都不得不生活在他的阴影下。阿尔布雷希特·丢勒对版画做了同样的事情,简·奥斯汀对小说做了同样的事情。
我们一次又一次地看到同样的模式。新媒体出现,人们对它如此兴奋,以至于他们在头几代人中探索了其大部分可能性。黑客现在似乎处于这个阶段。
在莱昂纳多的时代,绘画并不像他的工作帮助使其变得那么酷。黑客最终会有多酷取决于我们能用这种新媒体做什么。
注释
[1] 摄影对绘画造成的最大损害可能是它杀死了最好的日常工作。历史上大多数伟大的画家通过画肖像来维持生计。
[2] 有人告诉我,微软阻止员工为开源项目做贡献,即使在业余时间也是如此。但现在有这么多最好的黑客在开源项目上工作,这个政策的主要效果可能是确保他们将无法雇佣任何一流的程序员。
[3] 你在大学里学到的关于编程的知识很像你学到的关于书籍、衣服或约会的知识:你在高中时有多糟糕的品味。
[4] 这是应用同理心的一个例子。在Viaweb,如果我们不能在两个备选方案之间做决定,我们会问,我们的竞争对手最讨厌什么?有一次,一个竞争对手在他们的软件中添加了一个基本无用的功能,但因为这是少数我们没有的功能之一,他们在行业媒体上大肆宣传。我们可以尝试解释这个功能是无用的,但我们决定如果我们只是自己实现它,会更烦我们的竞争对手,所以我们在那天下午匆匆拼凑了我们自己的版本。
[5] 除了文本编辑器和编译器。黑客不需要同理心来设计这些,因为他们自己就是典型用户。
[6] 嗯,差不多。他们有点超出了可用的RAM,造成了很多不便的磁盘交换,但这可以在几个月内通过购买额外的磁盘驱动器来解决。
[7] 使程序易于阅读的方法不是用注释填充它们。我会将阿贝尔森和苏斯曼的引语更进一步。编程语言应该被设计用来表达算法,只是顺便告诉计算机如何执行它们。一个好的编程语言应该比英语更适合解释软件。只有当你需要警告读者某种拙劣的东西时才需要注释,就像在路上只在有意外急转弯的部分才有箭头。
感谢特雷弗·布莱克威尔、罗伯特·莫里斯、丹·吉芬和丽莎·兰德尔阅读本文的草稿,感谢亨利·莱特纳和拉里·芬克尔斯坦邀请我演讲。
日语翻译 | 西班牙语翻译 | 德语翻译 | 葡萄牙语翻译 | 捷克语翻译
好设计来自坏设计 | 克努特:计算机编程作为艺术
你将在《黑客与画家》中找到这篇论文和其他14篇。
Hackers and Painters
May 2003
(This essay is derived from a guest lecture at Harvard, which incorporated an earlier talk at Northeastern.)
When I finished grad school in computer science I went to art school to study painting. A lot of people seemed surprised that someone interested in computers would also be interested in painting. They seemed to think that hacking and painting were very different kinds of work— that hacking was cold, precise, and methodical, and that painting was the frenzied expression of some primal urge.
Both of these images are wrong. Hacking and painting have a lot in common. In fact, of all the different types of people I’ve known, hackers and painters are among the most alike.
What hackers and painters have in common is that they’re both makers. Along with composers, architects, and writers, what hackers and painters are trying to do is make good things. They’re not doing research per se, though if in the course of trying to make good things they discover some new technique, so much the better.
I’ve never liked the term “computer science.” The main reason I don’t like it is that there’s no such thing. Computer science is a grab bag of tenuously related areas thrown together by an accident of history, like Yugoslavia. At one end you have people who are really mathematicians, but call what they’re doing computer science so they can get DARPA grants. In the middle you have people working on something like the natural history of computers— studying the behavior of algorithms for routing data through networks, for example. And then at the other extreme you have the hackers, who are trying to write interesting software, and for whom computers are just a medium of expression, as concrete is for architects or paint for painters. It’s as if mathematicians, physicists, and architects all had to be in the same department.
Sometimes what the hackers do is called “software engineering,” but this term is just as misleading. Good software designers are no more engineers than architects are. The border between architecture and engineering is not sharply defined, but it’s there. It falls between what and how: architects decide what to do, and engineers figure out how to do it.
What and how should not be kept too separate. You’re asking for trouble if you try to decide what to do without understanding how to do it. But hacking can certainly be more than just deciding how to implement some spec. At its best, it’s creating the spec— though it turns out the best way to do that is to implement it.
Perhaps one day “computer science” will, like Yugoslavia, get broken up into its component parts. That might be a good thing. Especially if it meant independence for my native land, hacking.
Bundling all these different types of work together in one department may be convenient administratively, but it’s confusing intellectually. That’s the other reason I don’t like the name “computer science.” Arguably the people in the middle are doing something like an experimental science. But the people at either end, the hackers and the mathematicians, are not actually doing science.
The mathematicians don’t seem bothered by this. They happily set to work proving theorems like the other mathematicians over in the math department, and probably soon stop noticing that the building they work in says “computer science” on the outside. But for the hackers this label is a problem. If what they’re doing is called science, it makes them feel they ought to be acting scientific. So instead of doing what they really want to do, which is to design beautiful software, hackers in universities and research labs feel they ought to be writing research papers.
In the best case, the papers are just a formality. Hackers write cool software, and then write a paper about it, and the paper becomes a proxy for the achievement represented by the software. But often this mismatch causes problems. It’s easy to drift away from building beautiful things toward building ugly things that make more suitable subjects for research papers.
Unfortunately, beautiful things don’t always make the best subjects for papers. Number one, research must be original— and as anyone who has written a PhD dissertation knows, the way to be sure that you’re exploring virgin territory is to stake out a piece of ground that no one wants. Number two, research must be substantial— and awkward systems yield meatier papers, because you can write about the obstacles you have to overcome in order to get things done. Nothing yields meaty problems like starting with the wrong assumptions. Most of AI is an example of this rule; if you assume that knowledge can be represented as a list of predicate logic expressions whose arguments represent abstract concepts, you’ll have a lot of papers to write about how to make this work. As Ricky Ricardo used to say, “Lucy, you got a lot of explaining to do.”
The way to create something beautiful is often to make subtle tweaks to something that already exists, or to combine existing ideas in a slightly new way. This kind of work is hard to convey in a research paper.
So why do universities and research labs continue to judge hackers by publications? For the same reason that “scholastic aptitude” gets measured by simple-minded standardized tests, or the productivity of programmers gets measured in lines of code. These tests are easy to apply, and there is nothing so tempting as an easy test that kind of works.
Measuring what hackers are actually trying to do, designing beautiful software, would be much more difficult. You need a good sense of design to judge good design. And there is no correlation, except possibly a negative one, between people’s ability to recognize good design and their confidence that they can.
The only external test is time. Over time, beautiful things tend to thrive, and ugly things tend to get discarded. Unfortunately, the amounts of time involved can be longer than human lifetimes. Samuel Johnson said it took a hundred years for a writer’s reputation to converge. You have to wait for the writer’s influential friends to die, and then for all their followers to die.
I think hackers just have to resign themselves to having a large random component in their reputations. In this they are no different from other makers. In fact, they’re lucky by comparison. The influence of fashion is not nearly so great in hacking as it is in painting.
There are worse things than having people misunderstand your work. A worse danger is that you will yourself misunderstand your work. Related fields are where you go looking for ideas. If you find yourself in the computer science department, there is a natural temptation to believe, for example, that hacking is the applied version of what theoretical computer science is the theory of. All the time I was in graduate school I had an uncomfortable feeling in the back of my mind that I ought to know more theory, and that it was very remiss of me to have forgotten all that stuff within three weeks of the final exam.
Now I realize I was mistaken. Hackers need to understand the theory of computation about as much as painters need to understand paint chemistry. You need to know how to calculate time and space complexity and about Turing completeness. You might also want to remember at least the concept of a state machine, in case you have to write a parser or a regular expression library. Painters in fact have to remember a good deal more about paint chemistry than that.
I’ve found that the best sources of ideas are not the other fields that have the word “computer” in their names, but the other fields inhabited by makers. Painting has been a much richer source of ideas than the theory of computation.
For example, I was taught in college that one ought to figure out a program completely on paper before even going near a computer. I found that I did not program this way. I found that I liked to program sitting in front of a computer, not a piece of paper. Worse still, instead of patiently writing out a complete program and assuring myself it was correct, I tended to just spew out code that was hopelessly broken, and gradually beat it into shape. Debugging, I was taught, was a kind of final pass where you caught typos and oversights. The way I worked, it seemed like programming consisted of debugging.
For a long time I felt bad about this, just as I once felt bad that I didn’t hold my pencil the way they taught me to in elementary school. If I had only looked over at the other makers, the painters or the architects, I would have realized that there was a name for what I was doing: sketching. As far as I can tell, the way they taught me to program in college was all wrong. You should figure out programs as you’re writing them, just as writers and painters and architects do.
Realizing this has real implications for software design. It means that a programming language should, above all, be malleable. A programming language is for thinking of programs, not for expressing programs you’ve already thought of. It should be a pencil, not a pen. Static typing would be a fine idea if people actually did write programs the way they taught me to in college. But that’s not how any of the hackers I know write programs. We need a language that lets us scribble and smudge and smear, not a language where you have to sit with a teacup of types balanced on your knee and make polite conversation with a strict old aunt of a compiler.
While we’re on the subject of static typing, identifying with the makers will save us from another problem that afflicts the sciences: math envy. Everyone in the sciences secretly believes that mathematicians are smarter than they are. I think mathematicians also believe this. At any rate, the result is that scientists tend to make their work look as mathematical as possible. In a field like physics this probably doesn’t do much harm, but the further you get from the natural sciences, the more of a problem it becomes.
A page of formulas just looks so impressive. (Tip: for extra impressiveness, use Greek variables.) And so there is a great temptation to work on problems you can treat formally, rather than problems that are, say, important.
If hackers identified with other makers, like writers and painters, they wouldn’t feel tempted to do this. Writers and painters don’t suffer from math envy. They feel as if they’re doing something completely unrelated. So are hackers, I think.
If universities and research labs keep hackers from doing the kind of work they want to do, perhaps the place for them is in companies. Unfortunately, most companies won’t let hackers do what they want either. Universities and research labs force hackers to be scientists, and companies force them to be engineers.
I only discovered this myself quite recently. When Yahoo bought Viaweb, they asked me what I wanted to do. I had never liked the business side very much, and said that I just wanted to hack. When I got to Yahoo, I found that what hacking meant to them was implementing software, not designing it. Programmers were seen as technicians who translated the visions (if that is the word) of product managers into code.
This seems to be the default plan in big companies. They do it because it decreases the standard deviation of the outcome. Only a small percentage of hackers can actually design software, and it’s hard for the people running a company to pick these out. So instead of entrusting the future of the software to one brilliant hacker, most companies set things up so that it is designed by committee, and the hackers merely implement the design.
If you want to make money at some point, remember this, because this is one of the reasons startups win. Big companies want to decrease the standard deviation of design outcomes because they want to avoid disasters. But when you damp oscillations, you lose the high points as well as the low. This is not a problem for big companies, because they don’t win by making great products. Big companies win by sucking less than other big companies.
So if you can figure out a way to get in a design war with a company big enough that its software is designed by product managers, they’ll never be able to keep up with you. These opportunities are not easy to find, though. It’s hard to engage a big company in a design war, just as it’s hard to engage an opponent inside a castle in hand to hand combat. It would be pretty easy to write a better word processor than Microsoft Word, for example, but Microsoft, within the castle of their operating system monopoly, probably wouldn’t even notice if you did.
The place to fight design wars is in new markets, where no one has yet managed to establish any fortifications. That’s where you can win big by taking the bold approach to design, and having the same people both design and implement the product. Microsoft themselves did this at the start. So did Apple. And Hewlett-Packard. I suspect almost every successful startup has.
So one way to build great software is to start your own startup. There are two problems with this, though. One is that in a startup you have to do so much besides write software. At Viaweb I considered myself lucky if I got to hack a quarter of the time. And the things I had to do the other three quarters of the time ranged from tedious to terrifying. I have a benchmark for this, because I once had to leave a board meeting to have some cavities filled. I remember sitting back in the dentist’s chair, waiting for the drill, and feeling like I was on vacation.
The other problem with startups is that there is not much overlap between the kind of software that makes money and the kind that’s interesting to write. Programming languages are interesting to write, and Microsoft’s first product was one, in fact, but no one will pay for programming languages now. If you want to make money, you tend to be forced to work on problems that are too nasty for anyone to solve for free.
All makers face this problem. Prices are determined by supply and demand, and there is just not as much demand for things that are fun to work on as there is for things that solve the mundane problems of individual customers. Acting in off-Broadway plays just doesn’t pay as well as wearing a gorilla suit in someone’s booth at a trade show. Writing novels doesn’t pay as well as writing ad copy for garbage disposals. And hacking programming languages doesn’t pay as well as figuring out how to connect some company’s legacy database to their Web server.
I think the answer to this problem, in the case of software, is a concept known to nearly all makers: the day job. This phrase began with musicians, who perform at night. More generally, it means that you have one kind of work you do for money, and another for love.
Nearly all makers have day jobs early in their careers. Painters and writers notoriously do. If you’re lucky you can get a day job that’s closely related to your real work. Musicians often seem to work in record stores. A hacker working on some programming language or operating system might likewise be able to get a day job using it. [1]
When I say that the answer is for hackers to have day jobs, and work on beautiful software on the side, I’m not proposing this as a new idea. This is what open-source hacking is all about. What I’m saying is that open-source is probably the right model, because it has been independently confirmed by all the other makers.
It seems surprising to me that any employer would be reluctant to let hackers work on open-source projects. At Viaweb, we would have been reluctant to hire anyone who didn’t. When we interviewed programmers, the main thing we cared about was what kind of software they wrote in their spare time. You can’t do anything really well unless you love it, and if you love to hack you’ll inevitably be working on projects of your own. [2]
Because hackers are makers rather than scientists, the right place to look for metaphors is not in the sciences, but among other kinds of makers. What else can painting teach us about hacking?
One thing we can learn, or at least confirm, from the example of painting is how to learn to hack. You learn to paint mostly by doing it. Ditto for hacking. Most hackers don’t learn to hack by taking college courses in programming. They learn to hack by writing programs of their own at age thirteen. Even in college classes, you learn to hack mostly by hacking. [3]
Because painters leave a trail of work behind them, you can watch them learn by doing. If you look at the work of a painter in chronological order, you’ll find that each painting builds on things that have been learned in previous ones. When there’s something in a painting that works very well, you can usually find version 1 of it in a smaller form in some earlier painting.
I think most makers work this way. Writers and architects seem to as well. Maybe it would be good for hackers to act more like painters, and regularly start over from scratch, instead of continuing to work for years on one project, and trying to incorporate all their later ideas as revisions.
The fact that hackers learn to hack by doing it is another sign of how different hacking is from the sciences. Scientists don’t learn science by doing it, but by doing labs and problem sets. Scientists start out doing work that’s perfect, in the sense that they’re just trying to reproduce work someone else has already done for them. Eventually, they get to the point where they can do original work. Whereas hackers, from the start, are doing original work; it’s just very bad. So hackers start original, and get good, and scientists start good, and get original.
The other way makers learn is from examples. For a painter, a museum is a reference library of techniques. For hundreds of years it has been part of the traditional education of painters to copy the works of the great masters, because copying forces you to look closely at the way a painting is made.
Writers do this too. Benjamin Franklin learned to write by summarizing the points in the essays of Addison and Steele and then trying to reproduce them. Raymond Chandler did the same thing with detective stories.
Hackers, likewise, can learn to program by looking at good programs— not just at what they do, but the source code too. One of the less publicized benefits of the open-source movement is that it has made it easier to learn to program. When I learned to program, we had to rely mostly on examples in books. The one big chunk of code available then was Unix, but even this was not open source. Most of the people who read the source read it in illicit photocopies of John Lions’ book, which though written in 1977 was not allowed to be published until 1996.
Another example we can take from painting is the way that paintings are created by gradual refinement. Paintings usually begin with a sketch. Gradually the details get filled in. But it is not merely a process of filling in. Sometimes the original plans turn out to be mistaken. Countless paintings, when you look at them in xrays, turn out to have limbs that have been moved or facial features that have been readjusted.
Here’s a case where we can learn from painting. I think hacking should work this way too. It’s unrealistic to expect that the specifications for a program will be perfect. You’re better off if you admit this up front, and write programs in a way that allows specifications to change on the fly.
(The structure of large companies makes this hard for them to do, so here is another place where startups have an advantage.)
Everyone by now presumably knows about the danger of premature optimization. I think we should be just as worried about premature design— deciding too early what a program should do.
The right tools can help us avoid this danger. A good programming language should, like oil paint, make it easy to change your mind. Dynamic typing is a win here because you don’t have to commit to specific data representations up front. But the key to flexibility, I think, is to make the language very abstract. The easiest program to change is one that’s very short. This sounds like a paradox, but a great painting has to be better than it has to be. For example, when Leonardo painted the portrait of Ginevra de Benci in the National Gallery, he put a juniper bush behind her head. In it he carefully painted each individual leaf. Many painters might have thought, this is just something to put in the background to frame her head. No one will look that closely at it.
Not Leonardo. How hard he worked on part of a painting didn’t depend at all on how closely he expected anyone to look at it. He was like Michael Jordan. Relentless.
Relentlessness wins because, in the aggregate, unseen details become visible. When people walk by the portrait of Ginevra de Benci, their attention is often immediately arrested by it, even before they look at the label and notice that it says Leonardo da Vinci. All those unseen details combine to produce something that’s just stunning, like a thousand barely audible voices all singing in tune.
Great software, likewise, requires a fanatical devotion to beauty. If you look inside good software, you find that parts no one is ever supposed to see are beautiful too. I’m not claiming I write great software, but I know that when it comes to code I behave in a way that would make me eligible for prescription drugs if I approached everyday life the same way. It drives me crazy to see code that’s badly indented, or that uses ugly variable names.
If a hacker were a mere implementor, turning a spec into code, then he could just work his way through it from one end to the other like someone digging a ditch. But if the hacker is a creator, we have to take inspiration into account.
In hacking, like painting, work comes in cycles. Sometimes you get excited about some new project and you want to work sixteen hours a day on it. Other times nothing seems interesting.
To do good work you have to take these cycles into account, because they’re affected by how you react to them. When you’re driving a car with a manual transmission on a hill, you have to back off the clutch sometimes to avoid stalling. Backing off can likewise prevent ambition from stalling. In both painting and hacking there are some tasks that are terrifyingly ambitious, and others that are comfortingly routine. It’s a good idea to save some easy tasks for moments when you would otherwise stall.
In hacking, this can literally mean saving up bugs. I like debugging: it’s the one time that hacking is as straightforward as people think it is. You have a totally constrained problem, and all you have to do is solve it. Your program is supposed to do x. Instead it does y. Where does it go wrong? You know you’re going to win in the end. It’s as relaxing as painting a wall.
The example of painting can teach us not only how to manage our own work, but how to work together. A lot of the great art of the past is the work of multiple hands, though there may only be one name on the wall next to it in the museum. Leonardo was an apprentice in the workshop of Verrocchio and painted one of the angels in his Baptism of Christ. This sort of thing was the rule, not the exception. Michelangelo was considered especially dedicated for insisting on painting all the figures on the ceiling of the Sistine Chapel himself.
As far as I know, when painters worked together on a painting, they never worked on the same parts. It was common for the master to paint the principal figures and for assistants to paint the others and the background. But you never had one guy painting over the work of another.
I think this is the right model for collaboration in software too. Don’t push it too far. When a piece of code is being hacked by three or four different people, no one of whom really owns it, it will end up being like a common-room. It will tend to feel bleak and abandoned, and accumulate cruft. The right way to collaborate, I think, is to divide projects into sharply defined modules, each with a definite owner, and with interfaces between them that are as carefully designed and, if possible, as articulated as programming languages.
Like painting, most software is intended for a human audience. And so hackers, like painters, must have empathy to do really great work. You have to be able to see things from the user’s point of view.
When I was a kid I was always being told to look at things from someone else’s point of view. What this always meant in practice was to do what someone else wanted, instead of what I wanted. This of course gave empathy a bad name, and I made a point of not cultivating it.
Boy, was I wrong. It turns out that looking at things from other people’s point of view is practically the secret of success. It doesn’t necessarily mean being self-sacrificing. Far from it. Understanding how someone else sees things doesn’t imply that you’ll act in his interest; in some situations— in war, for example— you want to do exactly the opposite. [4]
Most makers make things for a human audience. And to engage an audience you have to understand what they need. Nearly all the greatest paintings are paintings of people, for example, because people are what people are interested in.
Empathy is probably the single most important difference between a good hacker and a great one. Some hackers are quite smart, but when it comes to empathy are practically solipsists. It’s hard for such people to design great software [5], because they can’t see things from the user’s point of view.
One way to tell how good people are at empathy is to watch them explain a technical question to someone without a technical background. We probably all know people who, though otherwise smart, are just comically bad at this. If someone asks them at a dinner party what a programming language is, they’ll say something like “Oh, a high-level language is what the compiler uses as input to generate object code.” High-level language? Compiler? Object code? Someone who doesn’t know what a programming language is obviously doesn’t know what these things are, either.
Part of what software has to do is explain itself. So to write good software you have to understand how little users understand. They’re going to walk up to the software with no preparation, and it had better do what they guess it will, because they’re not going to read the manual. The best system I’ve ever seen in this respect was the original Macintosh, in 1985. It did what software almost never does: it just worked. [6]
Source code, too, should explain itself. If I could get people to remember just one quote about programming, it would be the one at the beginning of Structure and Interpretation of Computer Programs. Programs should be written for people to read, and only incidentally for machines to execute. You need to have empathy not just for your users, but for your readers. It’s in your interest, because you’ll be one of them. Many a hacker has written a program only to find on returning to it six months later that he has no idea how it works. I know several people who’ve sworn off Perl after such experiences. [7]
Lack of empathy is associated with intelligence, to the point that there is even something of a fashion for it in some places. But I don’t think there’s any correlation. You can do well in math and the natural sciences without having to learn empathy, and people in these fields tend to be smart, so the two qualities have come to be associated. But there are plenty of dumb people who are bad at empathy too. Just listen to the people who call in with questions on talk shows. They ask whatever it is they’re asking in such a roundabout way that the hosts often have to rephrase the question for them.
So, if hacking works like painting and writing, is it as cool? After all, you only get one life. You might as well spend it working on something great.
Unfortunately, the question is hard to answer. There is always a big time lag in prestige. It’s like light from a distant star. Painting has prestige now because of great work people did five hundred years ago. At the time, no one thought these paintings were as important as we do today. It would have seemed very odd to people at the time that Federico da Montefeltro, the Duke of Urbino, would one day be known mostly as the guy with the strange nose in a painting by Piero della Francesca.
So while I admit that hacking doesn’t seem as cool as painting now, we should remember that painting itself didn’t seem as cool in its glory days as it does now.
What we can say with some confidence is that these are the glory days of hacking. In most fields the great work is done early on. The paintings made between 1430 and 1500 are still unsurpassed. Shakespeare appeared just as professional theater was being born, and pushed the medium so far that every playwright since has had to live in his shadow. Albrecht Durer did the same thing with engraving, and Jane Austen with the novel.
Over and over we see the same pattern. A new medium appears, and people are so excited about it that they explore most of its possibilities in the first couple generations. Hacking seems to be in this phase now.
Painting was not, in Leonardo’s time, as cool as his work helped make it. How cool hacking turns out to be will depend on what we can do with this new medium.
Notes
[1] The greatest damage that photography has done to painting may be the fact that it killed the best day job. Most of the great painters in history supported themselves by painting portraits.
[2] I’ve been told that Microsoft discourages employees from contributing to open-source projects, even in their spare time. But so many of the best hackers work on open-source projects now that the main effect of this policy may be to ensure that they won’t be able to hire any first-rate programmers.
[3] What you learn about programming in college is much like what you learn about books or clothes or dating: what bad taste you had in high school.
[4] Here’s an example of applied empathy. At Viaweb, if we couldn’t decide between two alternatives, we’d ask, what would our competitors hate most? At one point a competitor added a feature to their software that was basically useless, but since it was one of few they had that we didn’t, they made much of it in the trade press. We could have tried to explain that the feature was useless, but we decided it would annoy our competitor more if we just implemented it ourselves, so we hacked together our own version that afternoon.
[5] Except text editors and compilers. Hackers don’t need empathy to design these, because they are themselves typical users.
[6] Well, almost. They overshot the available RAM somewhat, causing much inconvenient disk swapping, but this could be fixed within a few months by buying an additional disk drive.
[7] The way to make programs easy to read is not to stuff them with comments. I would take Abelson and Sussman’s quote a step further. Programming languages should be designed to express algorithms, and only incidentally to tell computers how to execute them. A good programming language ought to be better for explaining software than English. You should only need comments when there is some kind of kludge you need to warn readers about, just as on a road there are only arrows on parts with unexpectedly sharp curves.
Thanks to Trevor Blackwell, Robert Morris, Dan Giffin, and Lisa Randall for reading drafts of this, and to Henry Leitner and Larry Finkelstein for inviting me to speak.
Japanese Translation | Spanish Translation | German Translation | Portuguese Translation | Czech Translation
Why Good Design Comes from Bad Design | Knuth: Computer Programming as an Art
You’ll find this essay and 14 others in Hackers & Painters.