30 秒看懂
2018 年 7 月的一个周四早上 7 点,Guido van Rossum 醒来,决定那场让人筋疲力尽的 PEP 572 之争,将是他最后一次让一项语言决策这样折磨自己。几个月后,他与 Lex Fridman 谈起这件事,从荷兰的战时小说和面包板电路讲到为什么他借用了 Python 最好的想法而不是自己发明,以及为什么他觉得自动驾驶汽车会先于数据中心产生意识。贯穿始终的脉络,与他的辞职邮件是一致的:他不只是发明了一门语言,而是把它养到了能够自己照顾自己的程度。
- 1被广为引用的辞职邮件那句话是:“你们所有人都要靠自己了。”Van Rossum 没有指定继任者,把民主、无政府、独裁和联邦制留给社区,作为一个悬而未决的问题。
- 2生命游戏才是简单系统中真正的谜题:规则简单到可以手算,但没有人能用经典数学描述它会产生什么。你必须把它运行起来。
- 3他知道大脑就是一台计算机,也知道 1970 年代的机器离大脑还很远,他看不出如何才能填平这道鸿沟这两个事实从来不互相矛盾。
- 4Python 从一条他给自己定下的规则开始:不要什么都从零设计,把你已经喜欢的功能借过来。缩进借自 ABC,字符串字面量和数字则来自 C。
- 5在他看来,训练神经网络算不上编程,那是另一类活动,正如用细胞培养器官并不会被叫作化学。
- 6他敢于离开,是因为他知道 Python 处于非常好的位置:五十到一百名核心开发者,大多数时候相处融洽,他们的专业能力已经覆盖了语言所需的各个方面。
按章节阅读完整文稿
善恶不是开关,晶体管也不是
Lex Fridman 开场的问题,规模更像哲学研讨课,而不是一场语言设计访谈。Van Rossum 1956 年出生在荷兰;他的父母那一代,和 Fridman 出身于苏联的家庭一样,都被第二次世界大战烙下了印记。人是天生善良或天生邪恶,还是我们每个人身上都同时带着善与恶?Van Rossum 没料到问题会这样深。他的回答很简单:我们每个人身上都有善与恶的潜力,而其中很大一部分取决于环境和情境。
十几岁时,他最喜欢的荷兰作家是 Willem Frederik Hermans,其早期小说写的是抵抗德国占领的暧昧世界。你永远分不清某个人到底是真正的抵抗者还是间谍,有些人物跨过了那条线,而读者始终不知道他们的结局。主角都是反英雄,在某种程度上都没能完成他们高远的目标。Van Rossum 至今仍读小说。他不认为小说直接影响他的技术工作,即便有人会把语言设计称为一门艺术。
他十几岁时的爱好是电子电路和机械模型。最初几年,他照着套件说明书做,并不真正理解电子学。他擅长调试,也非常仔细地遵循说明,这个习惯一直保留了下来。他对晶体管如何工作的理解很天真,对线圈和电容也没有真正的把握。等到数字电路变得复杂时,这种无知就成了问题:原理图看起来没问题,电路板却不工作,因为两根靠得太近的导线,或一个做得不好的开关,会在整块板子上引发兆赫级别的振荡。
生命游戏的奥妙在于,你必须运行它才能知道结果
十八岁时,他作为荷兰代表队的一员参加了东欧的数学奥林匹克。另一个书呆子同学跟他说起一种叫“计算机”的神奇东西。他从没听过这个词。他自己的电子制作,不过是些简单的数字电路;他以为自己多少懂一点计算器,却从没把两者联系起来。他甚至不知道,父母用打孔卡缴纳杂志订阅费时,其实有一台计算机在读这些卡片,并在账户之间转移资金。他当时没有兴趣。
大学里的数学课改变了这一切。学生可以使用计算机,也就是把程序打在打孔卡上,交给操作员,一小时后拿到打印结果。计算机与真实世界没有连接,你只能写一些抽象的东西。Van Rossum 没有看到科学怪人,也没有看到文字处理器或游戏机。他感兴趣的是折腾的过程。他说,他最后创造了一门编程语言,一个供其他程序员使用的工具,这并非完全是巧合。他始终关注编程这项活动本身,而不太关心你写的程序最后会被用来做什么。
大学二年级时,有人给他看了一份两页的复印件,内容来自《科学美国人》关于康威生命游戏的专栏。他用 Pascal 在批处理计算机上实现了它,从输入读取初始棋盘,逐代打印结果。他至今仍为其中一个硬件技巧感到自豪:他在纸上设计了一个逻辑门电路,接收九个比特(一个细胞及其邻居),输出下一代的值,然后把这个电路翻译成对 Pascal 整数(视为比特串)的布尔运算。大约八条指令就能算出一代中的六十个比特。Fridman 指出了这一点:Van Rossum 引以为傲的是这个技巧,画面本身倒不是重点。
原因很实际。学生的计算机时间是按量计费的,他曾因为超出了系里的预算而被教授训斥。他想要更大的棋盘和更多的代,这样就能输入各种图案(会平移一两格重新出现的滑翔机,以及滑翔机枪),看看会发生什么。Fridman 说,Stephen Wolfram 对此着迷,因为我们缺乏描述这种复杂性的数学,唯一的办法就是把系统运行起来。Van Rossum 并不认为它适合用经典数学分析。如果你想要真正的智能,恐怕不能指望用 Python 直接编写智能体,得先构建一个宇宙,再尝试大量规则集,直到找到一个不会坍缩成平凡重复的规则集。
大脑就是计算机,而 1970 年代的硬件远远不够
关于会思考的机器的流行讨论,几乎没有触动过他。十几岁时他几乎不读科幻,可能只读过一本故事集。他知道计算机有多少位内存、编程有多难,不相信用这些东西能造出符合他智能定义的智能体。让他眼界大开的书,是他二十出头读到的《哥德尔、艾舍尔、巴赫》,那是一本讨论意识的书。
他完全相信大脑在某种意义上就是计算机。大脑所遵循的规则与当前硬件实现的规则不同,但他不相信有某种独立的东西注入了智能或意识。“没有灵魂。”他从大约十岁起就是无神论者,那时他想了一些数学和宇宙的问题;他的父母也是无神论者。你可以是无神论者,同时坚持智能不可能从一套固定的规则中涌现。他并不属于这一派。
在他的叙述里,DNA 是一台特殊的机器,它以化学形式编码了无限量的信息,并找到了自我复制的方法。这种结构自数亿年前出现以来基本没有改变:就像一种二进制硬件,其基本编程语言保持不变,而用它写出的程序却发展出无穷的多样性。自我复制分子为了资源相互竞争,最终其中一类占据优势,这件事早在化石出现之前就已经发生了。他相信它确实发生过。他做学生时无法跨越的那道鸿沟属于工程问题,不属于形而上学。他能数出位数的那些计算机,离大脑实在太远了。
如果什么东西会产生意识,先来的会是自动驾驶汽车
关于意识,他小心地说明,这是一个私人话题。编写编程语言并不会朝着发展智能的方向前进。不过,作为一个热衷科普的读者,他并不认为意识是全有或全无的。猫、狗、老鼠都有某种形式的智能,鱼也有。进化花了很长时间。他感觉,通向人类智能形式的道路,是沿着感官的进化走过来的,尤其是视觉。解读一个场景需要海量的运算,而人类在这方面仍然比计算机强。
他猜想,哺乳动物发展出不同层次的意识,是因为它们是拥有高度发达感官、接收大量丰富感知信息的机器人。在基本的生存程序之上堆叠足够多这样的东西,就会出现我们看来像智能和自我意识的东西。他预计这种东西最先出现的地方,并不是某个哲学抽象。当他开车时,他不只是遵守交通规则,他还在读路况:这里是购物区;一位老太太正在过马路;有人抱着一摞信件,要去邮箱,所以他们会过马路,于是他不假思索地减了速。
把观察转化为对另一个意识,或对世界中另一个系统即将做什么的建模,这种能力无处不在,比如你会感觉到一棵树要倒了。所以,如果什么东西会产生意识,他预计会是自动驾驶汽车,而不是谷歌或亚马逊数据中心里那数十亿台计算机组成的网络。在这个框架下,意识是与人类互动的一项工程要求:你需要共情,需要理解对死亡的恐惧,需要对人类的欲望和缺陷做基本运算。狗就是存在的证明。狗对身边的人会做什么,有一套模型。它们会学习,会难过,会哭,会因为受过虐待而害怕。我们不会认为它们拥有多少意识,但他也不认为它们完全没有。
笛卡尔有逻辑,却没有模式匹配
Fridman 把故事拉回十七世纪:莱布尼茨、霍布斯、笛卡尔,以及一种感觉,即所有思维、大脑中所有特别的东西,都可以转化为逻辑。把知识形式化,然后计算。这就是大脑在做的事。Van Rossum 的反驳很具体。那些思想家确实发现了非凡的数学,比如牛顿的微积分,并沿着这条路扩展了逻辑的能力。但他们没有意识到,识别一张脸并不是一堆规则。它是海量的数据,加上一个能解读视觉线索和语境、并能对存储的结构进行大规模并行模式匹配的电路。
他有一个具体的失败模式。如果明天在 Dropbox 办公室门口见到 Fridman,即使他换了件衬衫,他也可能认得出来。但如果在贝尔蒙特(Belmont)的咖啡馆,或在海滩上遇到,他可能完全认不出来。他经常犯这种错误:一个他只认识为妻子同事的人,在电影院里撞见,却怎么也对不上号。Fridman 追问:每一刻你都会获取关于场景的几万条信息(黑色衬衫、身高、是个人),并将它们汇总。难道这些不能被编码,最终被计算出来吗?
Van Rossum 把答案拆开来讲。这里并没有真正的魔法。不过,从进入眼睛和耳朵的信息,到对场景的理解,中间的抽象层级足够多,他认为 AI 还远没有走完这段距离。人体由原子构成,这种说法在这里毫无帮助,属于过度还原。一个身体包含器官;器官由细胞组成;细胞是蛋白质的集合;蛋白质由氨基酸连接而成;氨基酸则由原子组成,再往下便是量子力学。每一层都是真实的,但你没法用量子力学去理解身体。Fridman 补充说,仅仅知道我们由原子组成,还不足以让人对重造器官跃跃欲试。
编译器是一种感觉器官,层层都是编译器
他信赖的类比是编译器。解析器的输入例程,某种意义上就是一个感觉器官。它并不保存一串线性排列的字节,它构建的是一个相当复杂的内部表示,即抽象语法树;借助这个结构产出有用的东西(硬件能够执行的机器码)之后,便把这棵树丢掉。当一条鱼或一只苍蝇接收到视觉信号时,他确信它们同样会构建某种数据结构。苍蝇的大脑层级也许少到,它的抽象不过是“这里比那里暗”,外加运动感知,这就是为什么你的手一挥,它就飞走了。这已经是一种关于运动的抽象。
我们拥有相似的机制,只是复杂得多。没有对运动非常好的抽象,你就无法开车。在此之上,我们还建立了更持久的数据结构:经过一些处理后,部分信息被存入记忆,回想时便可取用。通过重复十位数字来记住一个电话号码,是一种相当有意识的记忆方式。而认出一张脸,则是另一种。他不知道它是如何完成的,大脑为此有专门的硬件。他也不知道其中有多少是编码在 DNA 里的,又有多少是在零到三岁之间反复训练出来的。
因此,日常生活运行在最高的抽象层次上,我们并不意识到底层的细节。Fridman 说 turtles all the way down(层层都是乌龟)。Van Rossum 回答说 compilers all the way down(层层都是编译器)。那正是他想表达的意思。笛卡尔开启了一条思路,认为没有魔法,尽管笛卡尔也不得不把灵魂和身体分开,可能是出于政治原因。将人类思维形式化的工作,则经由罗素、哥德尔不完备定理和图灵机继续推进。Van Rossum 的版本是工程层面的,而非形而上学的:堆栈是真实的,魔法不存在,而堆栈的大部分仍未被命名。
软件 2.0 不算编程,软件 1.0 早就放弃了对正确性的证明
编程能否继续攀登到更高的抽象层次?Van Rossum 认为,到了某个点,这些层次将不再被称为编程,也不再像源代码。下层仍然会有源代码,就像大脑里仍然有分子、电子和蛋白质一样。仍然会有编程和系统管理,保证机器运转。而机器所做的事情,位于另一个层次上。作为外行,他看到的人脸识别和自动驾驶的进步,来自海量的训练数据,而发表这些成果的研究者,未必确切知道他们的算法是如何运作的。
“算法”这个词让他很不舒服。Facebook 相关的新闻报道在用这个词时,含义和他十岁或八岁时学到的完全不同:那是一组你完全理解、可以做数学分析、可以证明其性质的规则。你可以证明埃拉托斯特尼筛法能产生所有素数,且只产生素数。Fridman 引用了 Andrej Karpathy 对另一种东西的俏皮称呼:软件 2.0(Software 2.0),即学习从输入到输出映射的神经网络。你无法看进去,你能做的只有训练。Van Rossum 不会把那称为编程,那是另一种活动,就像用细胞构建器官不能叫化学一样。
他喜欢一句老生常谈:AI 完成的每一项任务,一旦人们弄清楚它是怎么做到的,就不再被称为人工智能。一个新的科学或工程领域会把这个名字拿走。他或许过于在意术语,但他预计,会出现不同的概念,由受过不同教育、对自己的目标有不同模型的人提出。更深层的转变是统计性的。对神经网络,你只能说它在所有测试过的情况下 99.9% 的时间都能工作,而它失败的方式出人意料,甚至连例子都举不出来。Van Rossum 指出,编程 1.0 其实早已如此。大多数开发者早就放弃了无 bug 程序的理想。他们在意的是那些出现得足够频繁、足以令人烦恼的 bug,而偶尔的崩溃则被视为理所当然,因为程序员不够多,无法让所有代码都正确,而形式化方法又让工作变得更加繁琐。
如果一次想解决所有痒点,结果就什么也解决不了
用户点击了一个链接,出现错误,于是再点一次,它常常神奇地就好了,或者他们换一条路径。这就是一种端到端的恢复机制。系统内部有重试、超时和回退机制。Van Rossum 想象,生物系统里应该更是充满了这些机制,否则它们早就无法存活。基础编程教育掩盖了这一事实。学生写的程序如此之小,只要有 bug,你总能找到它。高中和大学的入门课程,都是小规模的编程。很少有课程教授软件工程,也就是构建大型系统。
每年夏天,这次访谈录制所在的 Dropbox,以及西海岸的每一家科技公司,都会招收大量实习生。实习生总是感到震惊。这是他们第一次亲眼看到大型软件开发环境里是怎样运作的。他们在大学里学到的一切,针对的都是小得多的规模,而规模的差异会在做事的方式和思考的方式上造成质的不同。1970 和 1980 年代他构想 Python 时,是否想象过像谷歌、Facebook 和 Dropbox 那样庞大的系统?他对计算领域的几乎每个阶段,都感到出乎意料。
他很庆幸自己当时没有意识到社区的每一个痒点。如果你试图同时解决所有问题,你就什么也解决不了。他的问题很聚焦:一门介于 shell 脚本和 C 之间的语言,一个能让他在非常特定的环境中作为程序员更有生产力的工具。他给自己定了大约三个月的时间预算,既包括设计(思考句法和语义特征),也包括实现,即从解析源代码到执行的整条流程。他已经从 ABC 那里拿来了好东西,而 ABC 他曾参与实现,尽管他并没有参与它的设计。恰恰是不知道自己缺什么,救了他。
Python 是面包板:借来你喜欢的,摇一摇,直到能跑起来
Fridman 在 1990 年代和 2000 年代用 C++ 做机器学习研究,而机械和电气专业的同事都在用 MATLAB。过去十年,神经网络的软件包都是基于 Python 构建的,他换了过去,并明显感觉到完成工作的效率大幅提升。他说不太清楚这种质的差异到底在哪里。然后他说出了:在 C++ 里,他喜欢写高性能的代码,搭建漂亮的结构,尤其是借助新标准的模板。但他发现自己大部分时间都花在那个结构上,而不是解析文件、提取几个关键词。
Van Rossum 仍然写 C,也仍然写 shell,但他的大多数东西都是用 Python 写的。有时任务需要其他语言,而大多数时候,任务通常更像“修复现有程序 X 中的一个 bug”,或者给一个大型程序添加一个小功能。即使没有约束,编写代码所需的时间和代码运行所需的时间之间也要权衡。在探索方案的阶段,你往往花在编写上的时间远多于运行,因为每次运行都会表明输出还不完全是你想要的。Python 让迭代更快:程序能编译运行之前,需要做对的细节更少,有庞大的库,有现成的组件可以拼接,很快就能把原型跑起来。
这又回到了电子制作的爱好。他当年用面包板:一个铺得乱七八糟的电路,只要一抖就会失效,但它能工作,而他要的只是看到它工作,然后进入下一张原理图。等设计定型之后,你才会去考虑 PCB、焊接、电压波动、机械干扰。他对电子学的这些一无所知,但在代码上知道很多。怎样在三个月内发明出能产生那种感觉的句法?他没有这样做。他告诉自己,他不想从零设计一切,而要借用他喜欢的语言中的功能。一个十七岁的人做不到这一点,因为他们没有其他语言的经验。他当时已经三十多岁了,写过解析器,实现过 ABC,还花了多年时间与 ABC 的作者争论它的设计。缩进和部分句法来自 ABC;字符串字面量和数字的运作方式来自 C。Python 的好东西大多是借来的。
Python 3 是为了解决那些只会越来越糟的毛病而出现的
三十年来,van Rossum 拥有一个古怪而务实的头衔:终身仁慈独裁者(BDFL)。Python 3 打破了与 Python 2 的向后兼容,是 Fridman 想要讨论的案例。这是一个群体过程。即便在名义上是 BDFL,大家也尊重他作为语言设计的创造者和所有者的地位,他仍然在向所有人征求反馈。Python 3 的起因是,社区里有人指出了一些反复咬到用户的问题:能不能对这些 Python 的毛病做点什么?
在早期版本中,团队非常认真地对待向后兼容。许多毛病已经被解决了,因为它们能在保持兼容的前提下修复,或者沿着非常渐进的演化路径修复。剩下的都是广为人知的问题:它们算不上路障,倒更像人们每次都会绊倒的同一块绊脚石。团队想不出一种向后兼容的方式来解决它们,不解决也是一个选项。长期以来,他们已经接受了:这门语言在这里那里都不会完美。
许多细节在 Java、R 或 Visual Basic 里仍然做得更好,而他们对此也能接受:他们没法轻易改变,问题也不算太严重,他们可以通过用户教育、静态分析器或解析器中的警告来做一点补救。剩下的一些毛病则不同,这些问题不会自己消失,将来只会越来越糟。那时他们才决定应该做点什么。这是 Python 作为 BDFL 历史上最艰难的决定吗?Van Rossum 甚至不让这个问题有停留的余地。他说:“最艰难的决定,大概是辞职。”
最后一场 PEP 之争,也结束了独裁统治
2018 年 7 月,也就是这次录音的三个月前,他写道:既然 PEP 572 已经落定,他再也不想为了一个决定如此拼命地争斗,然后发现那么多人憎恶它。他想让自己彻底退出决策过程。他仍会作为一名普通核心开发者留在项目中,甚至可能更愿意指导他人,但他给自己放了一个永久的假期,不再担任 BDFL。他不会指定继任者:“你们所有人都要靠自己了。”那么社区会建立什么?民主、无政府、独裁,还是联邦制?Fridman 称这个开放式的姿态几乎有莎士比亚式的意味。Van Rossum 很高兴对方喜欢这段文字。那段文字写得很快。
PEP 572 是一个小功能:赋值表达式,也就是 := 海象运算符。Van Rossum 在其设计中出了很大力,尽管他并不是发起者。经过数月绕圈子之后,他批准了它。很多人声称自己知道什么才是 Pythonic,说这会毁掉这门语言,说它违背了 Python 最根本的设计哲学。他不予理会,因为他支持它,并认为自己对那种哲学有所了解。他又累又有压力。一个周三的晚上,他发出邮件:接受,接下来实现吧。他上床睡觉时如释重负。周四早上 7 点,他想:那是最后一场会如此糟糕的争论。那是我最后一次让自己为一个 PEP 决定如此焦虑,我应该干脆辞职。
他已经考虑退休有半个十年了,还开玩笑说社区不要太把“终身”二字当真。这一刻到了。他那天本来休假,想和妻子去附近一个小海滩小镇玩得开心。他大约用了十五到二十分钟,写下了 Fridman 所说的那段莎士比亚式的文字。他甚至没有意识到这是个多么重大的决定。五分钟后,他在 Twitter 上看到了一条指向他自己消息的链接,人们已经在讨论 Guido 辞去了 BDFL。他把它发在一个他以为只有核心开发者会看的内部论坛上,原以为至少会有一天时间,消息才会传出去。
“圣战”是爱好,把孩子养大才是骄傲
Fridman 把吉他当作爱好,而且得到的只有善意。作为编程社区的外部观察者,他经常看到阵营之分,而且这些阵营很激烈。Van Rossum 并不否认。圣战是程序员社区最喜欢的活动之一。如果大家只是互相拍背,从来不说真话,那就不好了。中间有一条路:彼此刻薄是不可以的,但健康、持续的批评与反馈,在每个层面上都非常有成效。有人提出一个小修复,审阅者说你可以用另一种方式做得更好。对于核心开发者社区的未来,他们已经有五六份相互竞争的章程提案。他认为这场辩论是健康而富有成效的。
他之所以写下辞职信,是因为他知道 Python 处于非常好的位置。写作或审查大部分 Python 代码的那五十到一百人,大多数时候相处得非常融洽。许多专业领域都有代表,核心内部的经验水平各不相同,核心之外的经验也各有不同:大型系统、小型系统、嵌入式系统。他觉得辞职没问题,因为他知道社区能够照顾自己。至于未来的话题,他没有那么浪漫。他并不那么希望 Python 会成为高并发、高并行的语言。它的设计、大多数用户的使用方式,以及它的实现方式,都让这种未来不太可能。异步 IO 是个特例:只是重叠 IO,而且只有 IO,这是支持高吞吐连接的方法,它会继续演化。并行计算不是 Python 的用途。你无法写出一个算法,然后让编译器把它并行化。你要使用 NumPy 之类的库,把数据和抽象操作告诉它们,然后你又回到了 C++ 的世界,这也正是 TensorFlow 在多 GPU 上接手的地方。
打包一直是他最不喜欢的话题。操作系统想要掌控打包,但它的解决方案并不针对某种特定语言:Linux 有相互竞争的跨语言系统,而 Node、Ruby 和 Python 各自都有自己的生态。他自己的做法,也是大多数人的做法,是用系统的打包工具安装 Python,用 Python 自己的工具安装第三方 Python 包。十年前,Python 打包的情况糟糕透顶。如今 pip 是未来。另有一个专门面向数值和科学计算的 Anaconda 生态,两者可以共存。他认为没有必要再多。
Fridman 看过那段五个半小时的计算机历史博物馆口述历史,感觉像是看完了一生精彩的人生。除了家人,回顾过去,他最自豪的是什么?“Python 绝对是我做过最好的事。”他不会只说是创造了 Python。他是像养孩子一样养大了它。他不只是孕育了一个孩子,而是养育了它,现在他把它放出去,让它在世界上自己照顾自己。他为此非常自豪。然后,正如《蒙提·派森的飞行马戏团》的报幕员过去常说的那样:现在来点完全不同的。Van Rossum 最喜欢的段子是死鹦鹉小品,Fridman 也是。Pushing up the daisies(长眠地下)。用这句话收尾,对一门语言,也对一位独裁者,都很合适。
同频道的其他文章
3:36:56EN → 简体中文
5:15:51EN → 简体中文
3:12:58EN → 简体中文
3:46:18EN → 简体中文
3:51:47EN → 简体中文
2:53:42EN → 简体中文