黑客与画家
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篇。