黑客和画家
Original2003年5月
(这篇文章来自我在哈佛大学的客座讲座,其中包含了我之前在东北大学的一次讲座。)
在我完成了计算机科学的研究生学习后,我去了艺术学院学习绘画。很多人似乎对一个对计算机感兴趣的人也对绘画感兴趣感到很惊讶。他们似乎认为编程和绘画是非常不同类型的工作 -- 编程是冷酷、精确和循序渐进的,而绘画则是某种原始冲动的狂乱表达。
这两种观点都是错误的。编程和绘画有很多共同之处。事实上,在我所认识的各种不同类型的人中,黑客和画家是最相似的。
编程和绘画的共同之处在于,他们都是制造者。与作曲家、建筑师和作家一起,黑客和画家正在努力创造出好的东西。他们不是在做纯学术研究,不过如果在努力创造好东西的过程中发现了一些新的技术,那就更好不过了。
我从来就不喜欢"计算机科学"这个术语。我不喜欢它的主要原因是,根本就没有这么一个东西。计算机科学是一个由历史偶然堆积起来的东西,就像南斯拉夫一样。在一端,你会遇到那些真正是数学家,但为了获得国防高级研究计划(DARPA)的拨款,他们称自己在做计算机科学。在中间,你会遇到那些在研究某种计算机的自然历史的人--比如研究用于在网络中传输数据的算法的行为。而在另一个极端,你会遇到那些试图编写有趣软件的黑客,对他们来说,计算机只是一种表达媒介,就像建筑师使用的混凝土或画家使用的油漆。这就好像数学家、物理学家和建筑师都必须在同一个系里。
有时,黑客们做的事情被称为"软件工程",但这个术语同样是误导性的。优秀的软件设计师并不比建筑师更像工程师。建筑和工程之间的边界并不是非常清晰,但它确实存在。它位于"什么"和"如何"之间:建筑师决定做什么,工程师则研究如何去做。
"什么"和"如何"不应该被过于分开。如果你试图在不了解如何去做的情况下决定做什么,那么你就麻烦大了。但编程绝不仅仅是决定如何实现某个规格。在最好的情况下,它就是在创造规格本身--尽管事实证明,最好的方式就是去实现它。
也许有一天,"计算机科学"会像南斯拉夫一样被分裂成它的各个组成部分。这可能是件好事。尤其是如果这意味着我的祖国--编程--获得独立的话。
将这些不同类型的工作捆绑在一个系里可能在行政上很方便,但在智力上却是令人困惑的。这是我不喜欢"计算机科学"这个名称的另一个原因。可以说,中间的那些人正在做某种实验性的科学。但两端的人--数学家和黑客--实际上并没有在做科学。
数学家似乎并不觉得有什么问题。他们愉快地投身于证明定理,就像数学系里的其他数学家一样,也许很快就不再注意到他们工作的那栋楼上写着"计算机科学"。但对于黑客来说,这个标签就成了一个问题。如果他们所做的被称为科学,那就会让他们觉得自己应该表现得很"科学"。
所以相比于做他们真正想做的事情--设计漂亮的软件,在大学和研究实验室里的黑客反而感到自己应该在写研究论文。
在最好的情况下,这些论文只是一种形式。黑客们编写了很酷的软件,然后写了一篇论文来介绍它,而这篇论文就成了代表这一软件成就的东西。但通常这种错位会带来问题。很容易从构建漂亮的东西转向构建丑陋的东西,因为后者更适合写研究论文。
遗憾的是,漂亮的东西并不总是最好的论文主题。首先,研究必须是原创的--正如任何写过博士论文的人都知道的,确保自己开拓处女领域的一个方法就是选择一个没有人愿意涉足的领域。其次,研究必须很扎实--而笨拙的系统会产生更丰富的论文,因为你可以写关于为了完成工作而必须克服的障碍。没有什么比从错误的假设开始更能产生丰富的问题了。人工智能大部分就是这样的例子;如果你假设知识可以用谓词逻辑表达式的列表来表示,其中的参数代表抽象概念,你就会有很多关于如何使这种方式奏效的论文要写。正如里基·里卡多(Ricky Ricardo)曾经说过的,"露西,你有很多事要解释呢。"
创造美丽事物的方法通常是对现有事物做细微的修改,或以略微不同的方式组合现有观念。这种工作很难在研究论文中表达。
那么,为什么大学和研究实验室还是用发表论文来评判黑客呢? 与"学习能力"用简单化的标准化测试来衡量,或用代码行数来衡量程序员的生产率,是一个道理。这些测试很容易应用,而且一种简单却勉强有用的测试是很诱人的。
要衡量黑客真正想要做的事情--设计漂亮的软件--要困难得多。你需要有良好的设计感来评判优秀的设计。而人们识别良好设计的能力与他们对自己能力的自信之间,除了可能存在负相关之外,几乎没有任何相关性。
唯一的外部测试是时间。随着时间推移,美丽的事物往往会茁壮成长,丑陋的事物则会被抛弃。不幸的是,涉及的时间可能长到超过人的一生。塞缪尔·约翰逊说,一个作家的声誉需要100年才能定型。你必须等待那个作家有影响力的朋友都死去,然后等待他们所有的追随者也死去。
我认为,黑客们只能认命于自己的声誉中有很大的随机成分。在这一点上,他们和其他制造者并没有什么不同。事实上,相比之下他们还算幸运。时尚在编程中的影响远远没有在绘画中那么大。
比起人们误解你的作品,还有比这更糟糕的事情。更危险的是,你自己会误解自己的作品。相关领域是你寻找创意的地方。如果你发现自己在计算机科学系,很自然地会相信,例如,黑客技术是理论计算机科学的应用版本。
我在研究生期间,脑海中一直有一种不安的感觉,即我应该知道更多的理论知识,忘记所有那些东西在期末考试后三周内,这是非常的疏忽。
现在我意识到这是错误的。黑客需要了解计算理论,就像画家需要了解油画化学一样。你需要知道如何计算时间和空间复杂性,以及图灵完备性。你也可能想记住状态机的概念,以防你需要编写解析器或正则表达式库。事实上,画家需要记住比那更多的油画化学知识。
我发现,最好的创意来源不是那些名称中带有"计算机"的其他领域,而是其他制造者所在的领域。绘画为我提供了比计算理论更丰富的创意源泉。
例如,我在大学里被教导,在接触计算机之前,应该完全在纸上设计好一个程序。但我发现自己并没有这样编程。我喜欢坐在电脑前编程,而不是在纸上。更糟糕的是,我没有耐心地写出一个完整的程序并确保它是正确的,而是倾向于只是吐出一些毫无希望的代码,然后慢慢将其打磨成型。我被教导,调试是一种最终的过程,用于捕捉打字错误和疏忽。而我的工作方式,似乎编程就是调试。
很长一段时间,我对此感到不好意思,就像我曾经觉得自己没有按照小学老师教的方式握笔一样。如果我只是看看其他制造者,画家或建筑师,我就会意识到,这种做法有一个名字:素描。就我所知,他们在大学教我的编程方式都错了。你应该在编写程序的同时去设计程序,就像作家、画家和建筑师所做的那样。
意识到这一点对软件设计确实有重要影响。这意味着一种编程语言应该首先是可塑的。编程语言是用来思考程序的,而不是用来表达你已经想好的程序。它应该是一支铅笔,而不是钢笔。如果人们真的像大学里教我的那样编写程序,静态类型可能是一个好主意。但这并不是我所认识的黑客们编写程序的方式。我们需要一种允许我们涂抹、模糊和涂改的语言,而不是一种你必须端坐在膝盖上平衡着一杯茶杯型类型,并与一位严格的编译器老伴客气聊天的语言。
说到静态类型,认同制造者的身份将使我们免于另一个困扰科学界的问题:数学羡慕症。每个人在科学界都暗自认为数学家比自己聪明。我想数学家也相信这一点。无论如何,结果是科学家倾向于让自己的工作看起来尽可能数学化。在物理学这样的领域,这可能没有太大危害,但越远离自然科学,这个问题就越严重。
一页公式看起来真的很令人印象深刻。(小贴士:为了增加震撼力,可以使用希腊字母变量。)因此,人们很容易着手解决那些可以正式处理的问题,而不是那些可能更重要的问题。
如果黑客认同其他制造者,如作家和画家,他们就不会感到数学羡慕症。作家和画家不会受到数学羡慕症的困扰。他们认为自己在做完全不同的事情。我想,黑客也是如此。
如果大学和研究实验室阻止黑客做他们想做的工作,也许公司才是他们的归宿。不幸的是,大多数公司也不会让黑客做他们想做的事情。大学和研究实验室迫使黑客成为科学家,公司则迫使他们成为工程师。
我自己最近才发现这一点。当雅虎收购Viaweb时,他们问我想做什么。我一直不太喜欢商业方面的工作,所以说我只想进行黑客编程。当我到雅虎后,我发现他们所说的黑客编程意味着实现软件,而不是设计软件。程序员被视为将产品经理的愿景(如果这是正确的词)转化为代码的技术人员。
这似乎是大公司的默认计划。他们这样做是为了降低结果的标准差。只有很小一部分黑客能够真正设计软件,公司的管理层很难挑选出这些人。所以,大多数公司不是让一个杰出的黑客负责软件的未来,而是设法让它由委员会设计,黑客只负责实现设计。
如果你想在某个时候赚钱,请记住这一点,因为这是创业公司能胜过大公司的原因之一。大公司想要降低设计结果的标准差,因为他们想避免灾难。但是,当你压制振荡时,你不仅会失去低点,也会失去高点。这对大公司来说并不是问题,因为他们不是靠制造出色的产品而获胜的。大公司赢的是因为他们的软件烂得不如其他大公司。
所以,如果你能想出一种方法,与一家足够大到其软件由产品经理设计的公司进行设计竞争,他们永远追不上你。不过,找到这样的机会并不容易。与大公司进行设计战是很难的,就像在城堡里与对手进行近身肉搏战一样。比如,很容易编写一个比微软Word更好的字处理器,但是微软在其操作系统垄断的城堡中,可能连你这样做都不会注意到。
设计战争的战场应该是在新的市场,那里还没有人建立起任何防御工事。这就是你通过大胆的设计方式,让同一批人负责设计和实现产品,就能大赢特赢的地方。微软、苹果和惠普在初期都是这么做的。我相信,几乎所有成功的初创公司都是如此。
因此,建造伟大软件的一个方法就是自己创办一家初创公司。不过,这里有两个问题。一个是在初创公司里,你不仅要编写软件,还要做很多其他事情。在威望软件公司里,我自认为已经很幸运了,因为我有四分之一的时间可以进行编程。其他三分之二的时间里,我要做从乏味到可怕的各种事情。我有一个基准可以判断这一点,那就是我曾经不得不离开一次董事会会议,去做一些补牙的工作。我记得坐在牙科诊椅上等待钻头时,觉得自己在度假。
创办初创公司的另一个问题是,能赚钱的软件和有趣的软件之间几乎没有重叠。编程语言很有趣,微软的第一个产品就是一种编程语言,但现在没有人愿意为编程语言付费。如果你想赚钱,往往就会被迫处理一些太复杂,没人愿意白白解决的问题。
所有的创造者都面临这个问题。价格由供给和需求决定,人们对有趣的事物的需求远不及对解决个人客户日常问题的需求。在离百老汇剧院很远的地方演出并不赚钱,就像在别人的展位里穿着大猩猩服装一样。写小说的报酬也没有为垃圾处理机编写广告复制那么高。编写编程语言的报酬也没有连接某公司的遗留数据库和网络服务器那么高。
我认为,对于软件来说,这个问题的答案是一个几乎所有创造者都了解的概念:日常工作。这个词起源于音乐家,他们在夜间表演。更普遍地说,它意味着你有一种为了挣钱而做的工作,另有一种是为了热爱而做的工作。
几乎所有的创造者在职业生涯的早期都有过日常工作。画家和作家尤其如此。如果你幸运的话,你可以找到一份与你真正工作紧密相关的日常工作。音乐家经常在唱片店工作。一个致力于某种编程语言或操作系统的黑客同样可能找到一份使用它的日常工作。[1]
当我说黑客应该有一份日常工作,并在业余时间从事美丽的软件创作时,我并不是在提出一个全新的想法。这就是开源黑客活动的本质。我要说的是,开源可能是正确的模式,因为所有其他类型的创造者也都独立地证实了这一点。
我觉得任何雇主都不应该不愿意让黑客参与开源项目,这让我感到很惊讶。在威望软件公司,如果一个程序员没有参与开源项目,我们会很不愿意雇用他。在面试程序员时,我们最关心的是他们业余时间都在写什么样的软件。你不可能做好任何事情,除非你热爱它,如果你热爱编程,你肯定会在自己的项目上工作。[2]
因为黑客是创造者而不是科学家,我们应该在其他创造者中寻找比喻,而不是在科学中。绘画能告诉我们什么关于编程的知识?
从绘画的例子中,我们可以学到或至少确认一点,那就是如何学习编程。你主要是通过实践来学习绘画。同样的,黑客也是通过自己编写程序来学习编程的,而不是通过上大学的编程课程。甚至在大学课堂上,你也主要是通过动手编程来学习编程。[3]
由于画家在作品中留下了痕迹,你可以观察他们是如何通过实践不断学习的。如果你按时间顺序看一个画家的作品,你会发现每一幅画都建立在前一幅画学到的东西之上。当一幅画中有某些元素非常出色时,你通常可以在更早期的某幅画中找到它的初始版本。
我认为,大多数创作者都是这样工作的。作家和建筑师似乎也是如此。也许黑客应该更像画家,定期从头开始,而不是继续在一个项目上工作多年,试图将所有后来的想法都纳入其中。
黑客是通过实践学习编程的事实,再次表明了编程与科学的不同。科学家不是通过做科研来学习科学的,而是通过做实验和练习题。科学家起初做的工作都是完美的,因为他们只是想复制别人已经完成的工作。后来,他们才能做原创性的工作。而黑客从一开始就在做原创性的工作,只是质量很差。所以黑客是从原创开始,然后变得优秀,而科学家是从优秀开始,然后变得原创。
创作者学习的另一种方式是通过学习范例。对于画家来说,美术馆就是他们的参考库。几百年来,模仿伟大画家的作品一直是画家传统教育的一部分,因为这种模仿迫使你仔细观察一幅画是如何创作的。
作家也是这样做的。本杰明·富兰克林通过总结亚迪生和斯蒂尔的文章要点,然后试图重现它们,来学习写作。雷蒙德·钱德勒也对侦探小说做过同样的事。
黑客也可以通过研究优秀的程序来学习编程--不仅要看它们做什么,还要看源代码。开源运动的一个鲜为人知的好处是,它使得学习编程变得更容易。当我学习编程时,我们主要依赖于书籍中的例子。当时可用的大块代码只有Unix,但即使这个也不是开源的。那些读过它源代码的人大多是通过约翰·莱昂斯的那本书的非法复印件,这本书虽然是在1977年写的,但直到1996年才获准出版。
从绘画中我们可以学到另一个例子,那就是绘画是通过逐步细化而创作的。绘画通常从草图开始。细节逐步填充。但这不仅仅是填充的过程。有时原计划被证明是错误的。许多绘画作品,当你用X光观察它们时,发现肢体已被移动或面部特征已被重新调整。
我们可以从绘画中学到这一点。我认为黑客工作也应该是这种方式。期望程序的规格说明会完美是不现实的。你最好承认这一点,并以允许规格说明实时变更的方式编写程序。
(大公司的结构使他们很难做到这一点,所以这里是初创公司的另一个优势所在。)
每个人现在都应该知道过早优化的危险性。我认为我们应该同样担心过早设计 - 过早决定程序应该做什么。
正确的工具可以帮助我们避免这种危险。一种好的编程语言应该,就像油画一样,让你改变主意很容易。动态类型是一个优势,因为你不必事先承诺特定的数据表示。但是灵活性的关键在于,我认为,使语言变得非常抽象。最容易改变的程序就是最简短的程序。
这听起来像是一个paradox,但一幅伟大的绘画作品必须比它必须做的更好。例如,当Leonardo为Ginevra de Benci画了国家美术馆的肖像时,他在她的头后画了一棵杜松子树。在上面,他仔细地画了每一片叶子。许多画家可能会认为,这只是一些用来给她的头部框定的背景。没有人会仔细看它。
不是Leonardo。他花在一幅画的某个部分上的努力,与他预计有人会如何注视它完全无关。他就像迈克尔·乔丹。执着。
执着会获胜,因为在总体上,看不见的细节会变得可见。当人们经过Ginevra de Benci的肖像时,他们的注意力通常会立即被吸引住,即使在他们看到标签并注意到它写的是Leonardo da Vinci之前。所有那些看不见的细节结合在一起,产生了一种令人惊叹的效果,就像一千个微弱的声音完美地合唱在一起。
同样地,伟大的软件也需要对美的狂热追求。如果你深入研究好的软件,你会发现即使是那些无人问津的部分也很美。我并不是声称我写的软件很棒,但是我知道,当涉及到代码时,我的行为会让我有资格服用处方药,如果我用同样的方式对待日常生活的话。看到代码缩进不当,或使用难看的变量名,会让我发疯。
如果一个黑客只是个实现者,把规格说明变成代码,那么他可以像挖沟一样从头到尾工作。但如果黑客是一个创造者,我们就必须考虑灵感。
在黑客工作中,就像在绘画中一样,工作都是循环进行的。有时你会对某个新项目感到兴奋,想一天工作16个小时。其他时候什么都不感兴趣。
要做出好的工作,你必须考虑这些循环,因为它们受你的反应影响。当你在山坡上开一辆手动变速器的汽车时,你有时必须松开离合器以避免熄火。退缩也可以防止野心熄火。在绘画和黑客工作中,有些任务令人生畏,有些则令人安慰。在你否则会熄火的时候,保留一些简单的任务是个好主意。
在黑客工作中,这可以实际意味着留下一些bug。我喜欢调试:这是黑客工作变得和人们认为的一样简单的唯一时候。你有一个完全受限的问题,你所要做的就是解决它。你的程序应该做x。但它却做了y。它在哪里出错了?你知道你最终会赢。这就像刷墙一样轻松。
绘画的例子不仅可以教会我们如何管理自己的工作,还可以教会我们如何共同工作。过去很多伟大的艺术作品都是多双手共同创作的结果,尽管博物馆里贴在旁边的只有一个名字。Leonardo是Verrocchio工作室的学徒,在他的洗礼作品中画了一个天使。这种情况是普遍的,而不是例外。米开朗基罗被认为特别勤奋,因为他坚持自己画西斯廷教堂天花板上的所有人物。
就我所知,当画家们共同创作一幅绘画时,他们从不在同一部分工作。通常主人会画主要人物,而助手会画其他人物和背景。但你从未见过一个人把另一个人的工作涂掉。
我认为这也是软件协作的正确模式。不要把它推得太远。当一段代码被三四个人同时"黑客"而没有人真正拥有它时,它会变得像一个公共房间,给人一种冷酷和被遗弃的感觉,并积累下垃圾。正确的协作方式是将项目划分为界限明确的模块,每个模块都有一个明确的所有者,模块之间的接口设计要像编程语言一样仔细和(如果可能)明确。
就像绘画一样,大部分软件都是为人类观众而创作的。所以黑客,就像画家一样,必须有同理心才能做出真正出色的作品。你必须能够从用户的角度来看待事物。
当我还是个孩子的时候,总有人告诉我要从别人的角度看问题。实际上,这总是意味着要做别人想要的事,而不是我想要的。这当然让同理心名声不太好,于是我刻意不培养它。
我错了。原来站在别人的角度看问题几乎是成功的秘诀。这并不意味着自我牺牲。恰恰相反,理解别人的观点并不意味着你会为他的利益而行动;在某些情况下——比如在战争中——你想要做完全相反的事。[4]
大多数制造者为人类受众制造东西。要吸引观众,你必须了解他们的需求。几乎所有最伟大的绘画作品都是人物画,因为人是人类最感兴趣的。
同情心可能是一个优秀黑客和一个出色黑客之间的最重要区别。一些黑客非常聪明,但在同情心方面几乎是独我论者。这样的人很难设计出出色的软件[5],因为他们无法从用户的角度看问题。
判断一个人同情心有多强的一个方法是观察他们如何向一个没有技术背景的人解释一个技术问题。我们可能都认识一些人,他们虽然在其他方面很聪明,但在这方面却可笑的糟糕。如果有人在晚宴上问他们什么是编程语言,他们会说类似"高级语言是编译器用作生成目标代码的输入"的话。高级语言?编译器?目标代码?显然不知道什么是编程语言的人也不会知道这些东西。
软件的一部分工作就是解释自己。所以要编写出好的软件,你必须了解用户知道多少。他们会毫无准备地走到软件面前,如果它不能按他们猜测的那样做,他们是不会去看手册的。我见过的最好的系统是1985年的原Macintosh。它做到了软件几乎从未做到过的事:它就是能工作。[6]
源代码也应该解释自己。如果我只能让人们记住一句关于编程的话,那就是《计算机程序的构造和解释》开头的那句。
程序应当为人类而写,只是顺带为机器执行。
你需要不仅对用户有同情心,对读者也要有同情心。这是出于自己的利益,因为你也会是其中的一员。许多黑客写了一个程序,六个月后回头看,自己都不知道它是如何工作的。我认识一些人,就是因为这种经历而发誓再也不用Perl了。[7]
缺乏同情心与智力有关,以至于在某些地方,它甚至成了一种时尚。但我不觉得两者之间有什么联系。你可以在数学和自然科学领域取得良好成绩,而不需要学习同情心,这些领域的人往往很聪明,所以这两种品质就产生了关联。但也有很多愚蠢的人同样缺乏同情心。只要听听打电话提问的人,他们提问的方式曲曲弯弯,主持人常常不得不帮他们重新表述问题。
那么,如果编程像绘画和写作,它有多酷?毕竟你只有一次人生。不妨把它用在做一些伟大的事情上。
不幸的是,这个问题很难回答。声望总是有很大的时滞。就像遥远星星的光芒。绘画现在享有的声誉是由于500年前那些伟大作品。当时,没人认为这些画作会有今天的重要性。Federico da Montefeltro 乌尔比诺公爵有一天会主要因为皮耶罗·德拉·弗朗西斯卡的一幅画中的那个奇怪鼻子而出名,在那个时代听起来会很奇怪。
所以,我承认编程现在可能不像绘画那么酷,但我们应该记住,绘画在鼎盛时期也没有现在这么酷。
我们可以确信的是,这是编程的鼎盛时期。在大多数领域,伟大的作品都是在最初期创造的。1430年到1500年之间创作的绘画作品至今仍无人能及。莎士比亚出现在专业剧院刚刚诞生的时期,并将这个媒体推向了如此高远的境地,以至于此后所有剧作家都不得不生存在他的阴影之下。阿尔布雷特·丢勒对雕刻,简·奥斯汀对小说也有同样的影响。
一次又一次,我们看到同样的模式在重复。一种新媒体出现,人们对它如此兴奋,以至于在最初的几代人中就探索了它的大部分可能性。编程似乎正处于这个阶段。
在达芬奇的时代,绘画并不像他的作品帮助它变得那么酷。编程最终会有多酷,取决于我们能用这种新媒体做些什么。
注释
[1] 摄影给绘画造成的最大伤害可能是杀死了最好的副业。历史上最伟大的画家大多通过作肖像画维持生计。
[2] 我被告知,微软公司不鼓励员工在业余时间参与开源项目,即使参与也会受到限制。但现在这么多最优秀的黑客都在参与开源项目,这一政策的主要效果可能是,他们将无法聘请任何一流的程序员。
[3] 你在大学学到的有关编程的知识,很像你在高中学到的有关书籍或服装或约会的知识:都是糟糕的品位。
[4] 这里有一个应用同情心的例子。在Viaweb工作时,如果我们在两个选择之间拿不定主意,我们会问:我们的竞争对手最不愿意看到的是什么?有一次,一个竞争对手给他们的软件增加了一个基本上毫无用处的功能,但由于这是他们少有的我们没有的功能之一,他们在贸易媒体上大肆宣传。我们本可以试图解释这个功能是无用的,但我们决定如果自己也实现这个功能,会更惹恼我们的竞争对手,所以我们就在当天下午匆忙制作了自己的版本。
[5] 除了文本编辑器和编译器。黑客们在设计这些工具时不需要同情心,因为他们本身就是典型的用户。
[6] 好吧,几乎可以。他们略有超出可用内存的设计,导致频繁的磁盘交换,但这可以通过在几个月内购买额外的磁盘驱动器来解决。
[7] 使程序易于阅读的方法不是在其中塞满注释。我会将阿贝尔森和苏斯曼的引语向前迈进一步。编程语言应该被设计用来表达算法,仅仅是偶尔告诉计算机如何执行它们。一种好的编程语言应该比英语更适合解释软件。您只有在需要警告读者某种 kludge 时才需要添加注释,就像在道路上只有在有意外陡峭的弯道时才会有箭头。
感谢 Trevor Blackwell、Robert Morris、Dan Giffin 和 Lisa Randall 阅读了这些草稿,以及 Henry Leitner 和 Larry Finkelstein 邀请我发表演讲。