咖啡与开源访谈 -- Ian Taylor
本内容是对 Coffee & Open Source Interview - Ian Taylor 的翻译与整理。
在节目中,Ian Taylor 讨论了他在开源社区的经历以及他在 Google 的工作。Ian Taylor 是 Google 的 Go 语言团队成员,他介绍了自己如何从早期的自由软件(如 GCC 编译器)过渡到参与开发 Go 语言。他讲述了自己从对编程的兴趣开始,到参与开源项目的经历,包括他在 GCC 和 Go 语言上的工作。他还分享了开源社区的变化以及个人如何在这个领域取得进展。
为符合中文惯用表达有适当删改, 版权归原作者所有.
Host: 你好,欢迎来到“咖啡与开源”,这是一个我们可以讨论开源话题、享受乐趣并了解社区中那些真正了不起的人的地方。今天我们的嘉宾是伊恩·泰勒,伊恩,跟大家打个招呼吧。
Ian: 嗨,大家好。
Host: 太好了,非常感谢你今天能来参加这个节目。
Ian: 嗯,没问题。
Host: 有件事我想澄清一下,伊恩其实是被‘推选’来做这个嘉宾的。我问了Go团队的一些人,是否有人愿意来做这个节目,大家都说‘找伊恩吧,他有丰富的开源经验’。所以我希望这次谈话能对很多人有所帮助。那么,伊恩,你能否简单介绍一下你自己和你现在的工作呢?
Ian: 当然可以。我叫伊恩·泰勒,或者在网络上叫伊恩·兰德斯凯勒。我在Google工作,已经在Google工作了大概14年。我在Go团队,主要从事Go语言的开发工作。我参与语言本身的开发,编译器的开发,还有标准库的开发。我在语言及其生态系统的很多方面都有所涉及。
Host: 太棒了。我在开源社区里经常听到一句话:‘我们都是站在巨人的肩膀上’。我们在使用那些别人辛苦开发出来的东西,而你在语言团队工作,我想这就像是一个没有多少人会关注的领域。显然,发明语言的人是‘名人’,但那些每天从事语言开发的人,似乎可以安静地做自己喜欢的事情,不会被太多人打扰。你有这种感觉吗?
Ian: 嗯,我觉得这很准确。我不知道语言设计者到底有多‘有名’,也许在一小部分人中他们是有名的。在技术圈里,确实有一些语言的创造者是广为人知的,但他们可以轻松地走进沃尔玛,而不会被认出来。
Host: 说得对。那么,你能否谈谈你是如何进入开源领域的?我想你应该在开源领域工作了很长时间了。
Ian: 当然可以。我在参与这次访谈之前也在回想这个问题。我在‘开源’这个词出现之前就开始从事相关工作了。那时候我们称之为‘自由软件’。当然,现在很多人仍然称之为‘自由软件’,我自己也经常用这个词。我第一次接触自由软件是在我成长的地方—马萨诸塞州剑桥。当时,任何人都可以进入哈佛科学中心,我经常路过那里去上高中。有一次,我看到一些海报,估计是理查德·斯托曼或他的朋友贴的,上面写着‘我要启动GNU项目,我要创造一个Unix的自由软件替代品’。当时还没有‘自由软件’这种说法,当然大部分软件是大家互相传递的,但并没有什么哲学意义上的附加。那就是我第一次接触自由软件,不过当时我还年轻,并没有马上参与进来。直到后来,大概1989年左右,我从大学毕业,有人向我展示了GNU编译器GCC,那是自由软件。我一直对编译器和语言很感兴趣,所以我开始玩弄这个编译器。当时我在一家处理一种非常冷门的计算平台Alpha Micro的公司工作。他们运行自己的操作系统,这在当时很常见。那不是Unix,也不是别的东西,而是叫做AMOS的系统。我把GCC移植到AMOS上,就是这样,我正式进入了自由软件领域。从那以后,我一直在不同的公司持续从事相关工作。
Host: 嗯,你现在在Google工作,对吧?
Ian: 是的,我现在在Google工作,已经大概14年了。
Host: 我要暴露我的年龄了,但我比很多进入开源领域的人要年轻一些。我第一次接触到的开源是HTML,那是我第一次觉得‘哇,这是真正的开源’。像JavaScript、HTML、CSS这些东西,你可以用它们构建任何东西,它们的规范非常明确。当我在大学时,我的教授们曾参与过FreeBSD项目,还有其他各种项目,他们总是讲述那些故事。我总是看着他们,心里想‘你们是怎么在基本上要从零开始构建这些基础设施的情况下生存下来的?’
你提到了理查德·斯托曼,提到了GNU项目。那么,在那个年代,开源或自由软件的概念在计算领域的氛围是怎么样的呢?我不清楚你是高中毕业后直接进入计算领域,还是大学毕业后才进入。但总的来说,当时在这个概念周围的氛围是怎样的?
Ian: 这是个有趣的问题,我不确定我能完全回答得准确。我在小学时就开始接触计算机了,不过按照今天的标准来看,那时候的一切都是非常原始的。但在当时,我们并不觉得自己是在‘石器时代’工作。我们在做的事情看起来很酷,很有趣。软件方面,当然有专有软件,但人们常常互相传递软件,告诉别人‘看,这是我在做的东西’。所以你说建立‘基础设施’这个说法很有趣,其实当时并没有这种感觉。显然我并不是计算机编程的真正开创者,但当我开始在GCC上工作,大概是1990年左右,我开始为其做贡献,后来我加入了一家公司,几乎全职从事GCC、汇编器和相关工具的开发。那时候感觉我们并不是在创造什么‘基础设施’,而是在为已经存在的工具集提供一个替代品,这些工具集是在Unix和其他系统上开发出来的。当时已经有了编译器,80年代90年代已经有了C语言,C++也开始崭露头角。所以我们做的是提供一个免费使用这些语言的途径,一个可以用来编写自己程序的免费工具集。我们把它看作是对现有代码的替代,而这些代码在各个Unix公司和微软当时被无理由地保密。
Host: 嗯,我说‘基础设施’有点开玩笑的意思,因为当你身处其中时,很难意识到你在创造历史。你可以数得出来,你有多少次在做某件事时,突然停下来意识到‘哦,这件事非常重要’。我觉得现在因为疫情等原因,大家更容易意识到历史正在发生。但在你日常工作中,谁知道20年、30年后,这些事情会成为‘经得起时间考验的’。这就是我为什么会用‘基础设施’这个词。
我回忆起我在大学时,教授们总是谈论打孔卡,因为这是他们对刚进入计算机领域的学生能讲的最好的故事—‘你知道我们当时要怎么做吗?’我总是想到打孔卡的场景,还有‘你要等一天才能知道自己做对了没有’这种情况,这对我们现在来说简直是天方夜谭。但听起来你是稍晚一些才进入这个领域,所以你进入时,已经有了编译器等工具,不再依赖机器来计算系统。
Ian: 是的,我母亲曾经用过打孔卡,所以我手里还有几张她的打孔卡。但我的第一次计算机体验是在个人电脑刚刚兴起的时候。我家里有一台TRS-80,是我父母给我买的。所以我有了自己的电脑,不用和别人分享。等我上大学时,大家都在使用分时系统,我们已经超越了那种把程序交给数据中心,然后等他们给出结果的时代。
Host: “你提到你是从TRS-80开始的。我想问一下,TRS-80是寄给你组装的,还是已经组装好的?"
Ian: TRS-80是由Radio Shack销售的,是一台完整的电脑,不需要自己组装。它是一体机,有键盘,感觉就像今天的笔记本电脑,只是大了很多。
Host: “你有没有把它拆开来研究,试图弄清楚它是怎么工作的?”
Ian: 嗯,不是特别多。我一直都是个软件人。我把它的软件部分‘拆开’了。它有一个ROM,里面装着Basic语言。你一开机,ROM里的Basic就会运行。我把整个ROM反汇编了,花了很长时间弄明白它是怎么工作的,这也是我第一次真正学习如何在低层次上编程。我没有反汇编器,所以我只是看着十六进制字节,然后理解Z80处理器是怎么工作的。然后我学会了如何为Basic语言编写扩展,这样我就可以画圆圈之类的图形,还写了一些游戏,这就是我当时做的事情。
Host: 你的父母可能很快就意识到你对这方面很感兴趣,所以才给你买了一台家用电脑。你还记得和父母讨论这件事的情景吗?因为你提到你母亲也在技术领域工作,他们是不是觉得这是你应该学的东西,还是你一直在这种环境中,所以自然而然地就对它产生了兴趣?
Ian: 我一直对它非常感兴趣,至于为什么,我已经记不清了。我觉得这东西很酷。当我大概七年级的时候,我和我姐姐,我父母说,‘好吧,你们每个人可以得到一个大礼物’,我说我想要一台电脑,我姐姐要了一匹马。实际上,那匹马的寿命远比电脑长。
Host: 是的,特别是在那个年代,电脑的寿命应该不会很长。现在他们说电脑的寿命大概是三年,尤其是笔记本电脑,如果你的笔记本电脑用了三年,是时候换一台了。家用电脑不太一样,因为你可以很容易地更换硬件。
然后你提到你上了大学,当时大家都在使用分时系统。那么,你是很快就决定要进入计算机领域,还是在大学期间才开始考虑其他职业选择的?
Ian: 我一直想成为一名计算机程序员。我在大学主修计算机科学,从一开始我就知道这是我要专注的方向,它对我来说一直很有趣,现在仍然如此。
Host: 我很好奇你在大学的经历。你提到这是在GNU项目宣布之后的一段时间。我想象一下,当时在大学里,计算机科学的学生几乎都呆在计算机实验室里。即使没有作业要做,大家也在实验室里,因为那是大家聚集的地方。你和那些一起分享经历以及对教授重复性作业不满的人,建立了非常深厚的友谊,对吧?
Ian: 是的,确实如此。
Host: 太棒了。你提到你毕业后加入了一个公司,你在那家公司主要负责GCC的开发,对吧?
Ian: 嗯,加入那家公司是我一个朋友创办的小公司。当时GCC还没进入我的视野,是后来GCC才出现,我开始玩弄它。
Host: 我看了你的简历,你列出了你参与的各种很酷的开源项目,真的很令人印象深刻。有哪一个项目在你工作的时候让你觉得‘哇,这真是太棒了,很多人会从中受益’?
Ian: 这是个有趣的问题。
Host: 或者我稍微换个问题。在你开发某个项目时,你有没有想过‘这个东西很多人会用到’,还是说你只是纯粹出于对技术的热爱?例如,你曾经参与Postgres的移植工作,对吧?在做这些工作时,你有没有想到‘这对社区来说会很有价值’,还是只是觉得‘我喜欢弄清楚这些东西是怎么工作的’?
Ian: 更多的是后者。至于对社区的价值,可能最接近的是UCP,这是我自己启动的一个项目。当时已经有一个UUC,这是计算机通过电话线传输文件的一种机制。很多电子邮件都是通过UUC发送的,还有一个叫做Usenet新闻的东西,不知道现在还有多少人知道Usenet。Usenet有点像公告板系统(BBS),但又有点不同,它是按主题组织的,文件在不同计算机之间传输,你可以在本地计算机上访问。Usenet比我所知道的任何公告板系统都要大。当时UUC有一个专有实现,是从AT&T出来的,大多数人都在用,但没有免费的版本。所以我觉得应该有一个免费的版本。
让我稍微更正一下,其实John Gilmore写过一个免费的版本,但它有一些缺陷,并没有包含所有功能,而且在某些情况下处理得不够好,至少在我当时看来是这样。所以我想,这里有一个空白点,我可以自己写一个免费的版本的ECP,这将是一个很酷的项目,也会很有趣,希望人们能从中受益。所以我并没有认为它会占据整个社区,因为在那个年代,我们都在为现有代码写免费的替代品,至少我是这样做的。人们没有现成的UCP可用,但这是一个他们可以使用的免费版本,他们可以根据自己的需要进行调整和自定义。
Host: 嗯,这也是我认为开源的价值所在之一。你可以直接使用开源软件,这对一些人来说非常有价值;或者,我认为开源的真正价值在于,你可以弄清楚它是如何工作的,然后根据自己的需要进行修改。我和很多人聊过,他们喜欢开源不是因为他们想要在互联网上出名,或者因为他们能找到任何他们想要的工作,而是因为他们希望人们能够理解他们构建这个东西的原因,并找到我从未想到的新方法来扩展它。
有一次,我在一个团队会议上,我们在讨论一个正在建设的系统。当时我们正在向一位高管汇报,他问道:“这很有趣,你能详细讲讲吗?”我们谈到了我们是如何从一种方式转变为另一种方式的。他们问我们为什么这么做,我们的回答是:“我们在开源社区中看到了一些非常类似的东西,但实现方式与我们的却有很大不同。”我们并不是要偷他们的创意,而是他们的想法触发了我们的思考,使我们的系统变得更加高效。正如任何好的高管所说的,“为什么你们一开始没有想到这个?”但我认为这是开源的一个好处。不仅仅是我们从开源世界中获取某些东西,然后尝试做一个免费的版本,还有机会让像微软、谷歌或亚马逊这样的公司,甚至任何公司,都可以看到开源领域中的好东西,然后说:“他们做得很好,我们应该尝试利用这一点。”我认为这在大部分情况下确实能让事情变得更加美好。
Ian: 是的,我完全同意。计算机编程是一个真的能从观察别人怎么做中获益的领域,分享想法,推动整个领域前进。
Host: 当你在做GCC的工作时,后来你可能换了工作或其他情况?或者你在GCC上工作了很长时间?我很好奇你是如何从一个项目过渡到另一个项目的,比如说“我做过这个,然后我做过那个,现在我是Go语言的设计者之一。”
Ian: 我在GCC上工作了很长时间。嗯,在我开始做ECP之后,我找了一份工作。当时我在做ECP时,暂时休息了一段时间,只是依靠有限的积蓄过活。后来我加入了一家叫做Cygnus的公司,当时叫做Cygnus Support,后来改名为Cygnus Solutions。他们完全是一家自由软件公司,这对我非常有吸引力。他们的主要收入来源是将GCC移植到新的微处理器上。这是在90年代中期,当时很多公司认为他们的出路是开发自己的微处理器,并将其应用到各种机器和设备中。为了做到这一点,他们当然需要一个编译器。我们发现,当时大多数人开始使用GCC,他们对GCC很熟悉,所以我们需要为我们的微处理器移植一个GCC版本。而且GCC恰好是自由软件,所以我们实际上可以获得一个移植版本,因为我们无法让那些专有编译器公司为我们的冷门微处理器移植编译器。所以他们来找Cygnus,请求我们为他们的微处理器编写一个移植版本,这样人们就可以编写C和C++代码了。我们就是这样做的,这是一个有点像机器的过程,我们可以在六个月内制作出一个新的移植版本,他们的微处理器就可以工作了。当然,现在几乎没有人记得这些微处理器了,事实证明这并不是一个很好的商业策略,但当时这是一个不错的生意。
然后,我还得说,我在那里继续从事GCC的工作,后来又为其他公司工作,主要还是做GCC的工作。实际上,我在谷歌被雇用也是为了GCC。
Host: 所以GCC在你的职业生涯中非常具有影响力。
Ian: 当然了,绝对是的。
Host: 所以当你开始从事GCC时,你有没有想过“嘿,我可以在这一领域工作一辈子”,或者说“我可以在这个领域工作”?
Ian: 我并不认为我会一直在GCC本身工作,尽管事实上我确实一直在做这方面的工作,但我确实觉得这是我喜欢的领域。我喜欢语言、编译器和工具,这是我在编程中最感兴趣的领域。
Host: 太棒了,后来你加入了谷歌。我们在开始录音前聊了一下,谈到了你现在正在做的工作。你想简单说一下你目前正在做的事情吗?然后我们可以谈谈它的历史。
Ian: 我在做Go编程语言的工作,实际上是涵盖了语言本身、标准库、围绕语言的工具、帮助社区等方面。而且,Go有一个GCC移植版本,你可以用它来编译Go代码,而这个移植版本是我写的。这也是我最初加入Go团队的原因。我在谷歌的时候听说了这个语言,它和我当时关于如何编写程序的一些想法很契合。而且,当时有一种新语言,我觉得非常酷,所以我想,这不是一个复杂的语言,我可以为这个语言写一个GCC移植版本,所以我就写了。我把它展示给Go团队,他们的反应是:“这很奇怪。”但很快我就加入了团队,并从那时开始工作。
Host: 那么他们说“奇怪”是好事还是坏事?
Ian: 我认为是好事,他们很惊讶。因为当时这个语言非常实验性。嗯,Go语言取得了惊人的成功,我对它的成功感到惊讶。但是,当我们开始时,我说“我们”,意思是他们开始这个项目,后来我加入团队,成为其中一员,我们当时的想法是,这些是一些不错的想法,让我们把这些想法发布出去,或许可以把它们引入到更成熟的语言中。我们只是想试试看,看看会如何发展。而人们真的接受了它。
Host: 我们在开始前简短地谈到了这一点,有些非常著名的项目是用Go语言编写的,比如我们谈到的Kubernetes和Docker。如果Docker当时选择使用C++或Kubernetes选择使用Java,Go语言是否会像现在这样受到关注?因为现在我觉得,如果你还没听说过Go语言,至少你应该在某种程度上了解它提供了其他语言所不具备的东西。我认为了解各种语言非常重要,你不需要成为专家,但至少在紧急情况下你可以写一个“Hello World”或是遍历一些数据源的循环代码。这样做是有价值的,它还能拓宽你的思维方式,因为编程语言本质上就是一种语言。显然,语言有不同的含义,但它们非常相似,你用代码说话,而不是用词语,这点我一直觉得很有趣。不过,我有点跑题了。
Ian: 我完全同意你的看法,这非常正确,学习新语言,无论是计算机语言还是人类语言都是很好的事情。正如你所说,它能让你学会用不同的方式解决问题。对我来说,作为一个学习西班牙语已经有13年的人来说,学习编程语言要容易得多。
Host: 嗯,现在谈谈Go语言吧。我们已经谈过一些了,现在它是一个非常成熟的解决方案,功能非常丰富,但社区中总有人在寻求新功能,期待语言的进步。所以,当你在制定语言功能扩展的计划时,这个过程是什么样的?
Ian: 嗯,首先让我说,我不会把Go描述为功能丰富的语言。我认为它有它所需要的功能,但总体上它是一个相对简单的语言。尤其是与C++这样的语言相比,Go的功能并不多。我们一直认为,简洁性是这门语言的一个关键方面。 再一次,我说“我们”,但我应该回到语言的创始阶段,尤其是Rob Pike,他真的很注重保持语言的简洁,易于学习和理解。所以,当我们在考虑为语言添加新功能时,这确实是我们主要关注的一个方面。我们不需要再增加一种做某事的方法,即使它可能更方便。除非它真的非常方便,否则我们才会考虑添加。目前,我们确实在认真研究为Go添加一个大功能,即泛型编程的支持,大多数其他现代语言都有这个功能,但Go还没有。所以我们一直在探讨如何在不增加语言复杂性的前提下获得所需的功能,同时保持易读性和易学性。这是我们努力保持的重点。
Host: 是的,你肯定不希望出现这样的情况:你添加了一个功能,然后人们的反应是“我必须重写所有代码才能利用这个功能。”像泛型这样的功能,我最早是在.NET中接触到它的,当.NET第一次添加泛型或C#第一个版本添加泛型时,这非常有趣。因为当时大多数其他语言都有某种形式的泛型,但要充分利用它,有很多代码需要重构。我会说,你有点过于谦虚了,因为如果Go没有所有编写这些东西所需的功能,你是不可能编写出像Docker或Kubernetes这样的东西的。但我认为任何一个生产力高的语言都会有社区提出的需求,尤其是我们现在处在一个人们非常喜欢函数式编程的世界中,而大多数主流编程语言都不是函数式的。所以,在不破坏一切的前提下添加函数式概念是非常有趣的。
Host: 我一直对Go语言有一个非常感兴趣的地方,当我第一次学习Go时,有一件事让我困惑不已,或许你能帮我理解它为什么这么重要。如果你调用一个函数,这个函数总是返回一个错误,即使没有错误,它也会返回一个错误。我一开始看到这个时觉得很不合理,为什么会有人这么做?但当我深入研究后,我发现这其实非常聪明,因为你不需要担心它是否返回错误。我想知道你对此的看法,因为这是与许多其他语言非常不同的地方。许多其他语言非常依赖于捕捉和抛出异常等机制。
Ian: 是的,很多语言使用异常来处理错误。我想最简单的表达我们观点的方式是,在编写程序时,错误并不是异常,错误无时无刻不在发生,原因各不相同。 你应该始终考虑到这些错误可能会发生,并决定如何处理这些错误。在使用异常的情况下,程序中会有一个额外的隐藏控制流路径遍布整个程序,你总是需要考虑,或者你应该总是考虑我现在要调用这个函数,它会返回,但它也可能突然抛出异常。如果抛出异常,它会穿过我当前的函数,所以我必须编写我的函数,确保它能够处理这种异常的传递,并且进行适当的清理工作。显然,带有异常处理的语言提供了所有你需要的结构来实现这一点,但关键是你必须始终考虑到这一点。而在Go中,我们不需要强迫人们去思考这些问题。如果人们必须始终去思考这些问题,那么在Go中,我们就将其显性化,让他们在那个时刻做出决定,而不是忘记异常的存在。这里有一个错误,我现在必须处理它,我可以选择忽略它,这没问题。
但是,你必须做出这个选择,并且明确表达这种选择。因此,当我在编写代码时,我必须考虑到这一点;而当别人阅读代码时,他们能够清楚地了解接下来会发生什么。当然,这意味着在Go语言中你会写更多的代码,因为你需要写更多关于如何处理错误的代码。我们和社区成员花了大量的时间和精力去改进和简化这个过程,但到目前为止,我们还没有找到一个完全令人满意的方法,我也不确定我们是否会找到。
尽管我说过Go语言没有异常处理机制,但它确实有一种抛出异常的方式,只是这种方式在普通编程中并不常用。Go语言有一个panic
函数,这个函数会导致程序中断运行,你可以从panic
中恢复,但这通常只在真正“例外”的情况下使用。 当系统资源面临风险,或者程序遇到了一些逻辑上不可能发生的情况时,panic
才会被使用。
Host: 我一直觉得有趣的是,当我在大学时,我们编写了一些程序,我已经不记得具体是什么了。我们在用Scheme(不知道你是否熟悉这个语言)编写一些递归相关的代码,因为Scheme非常擅长处理递归问题。
老师在我们提交作业后的第二天走进教室,他说他很惊讶,因为只有两位同学的程序导致了他的系统崩溃。这虽然令人印象深刻,但当你想到递归可能会做的事情时,就不难理解了。比如,它可能会耗尽所有内存或其他资源。
但你的观点是,在Go语言中,的确有些情况需要非常慎重对待。例如,这个程序可能会遇到非常糟糕的情况。这里有一个逻辑问题,比如说某个数字应该大于5,但实际值是4。虽然这在某些情况下是一个错误,但它并不属于“例外”情况。我觉得你的观点很有趣,因为在我的经验中,大多数主流编程语言都非常明确地要求你在遇到不理想的情况时以特定的方式处理。
所以,当我们谈论Go语言的一些其他功能时,像你提到的泛型,还有其他已经被其他语言采用的功能,你是否想在Go中引入一些更面向对象的特性,或者从其他函数式编程语言中借鉴一些功能?你有没有考虑过某些例子,比如C++中的某些特性,觉得如果Go有这个功能就好了?我注意到很多语言都会借鉴其他语言的特性,比如C#和Java经常从其他语言(尤其是函数式语言)中引入新特性。
Ian: 我们确实会时常查看其他语言,但我不会说我们是像你描述的那样来做的。从Go语言设计的初衷来看,我们更倾向于先用Go语言编写代码,看看在编写过程中遇到了哪些困难,哪些部分的代码难以编写。到那时,我们才会考虑其他语言是如何解决这些问题的,看看我们能否借鉴那些想法并将其引入Go。因此,我不会说我们是为了引入酷炫的新功能而去查看其他语言,而是说当我们遇到问题时,才会去寻找解决方案。
泛型绝对是我们目前最关注的一个大问题。另一个我能想到的领域是不可变性(immutability)。我并不是说Go一定会朝这个方向发展,但如果可能的话,这将是个有趣的探索。这里的发言会被记录并保留在互联网上,所以我必须非常小心。
在Go语言中,如果我们能够支持某种形式的不可变性,那将会非常有趣。比如,你可以在某个点之后声明某个变量不再改变,这会非常有用。另外,如果我们能够有一种方式来保证某个函数不会改变某个数据结构,那也会很棒。这种保证不一定需要在语言或编译器中实现,Go语言对分析工具有很强的支持。如果我们能够找到一种方法在程序中表达这一点,并且有工具可以验证它,这也是一种可接受的解决方案。我不知道我们在这个领域会做什么,也许我们永远不会做任何事情,但我觉得这将是一个很好的功能。
在C和C++中,这通常通过const
类型限定符来实现,但由于各种原因,这似乎并不适合Go语言。
Host: 我还想到,社区中总有一些人会说:“我来自C++或Java,但我很想念某个特性。”想必你经常会遇到这样的情况。我不知道你们通常如何处理这些新功能请求,人们是否会打开一个issue,或者通过讨论来提出这些需求。
Ian: 是的,我们确实有这样的建议流程。这个流程并不非常正式,但我们确实有一个流程,告诉大家如果你想对语言、标准库或支持工具进行更改,你应该怎么做。你可以提交一个issue,详细说明你的提议、背景、理由以及你具体想要更改的内容。然后我们会将其分为语言更改类和其他类(例如库和工具的更改),并进行审查。
这个审查过程目前不对公众开放,但我们会努力达成共识,确保所有相关的人都参与进来,指出需要解决的问题,并尽量达成社区共识,确定更改的方式。如果无法达成共识,我们通常会搁置该提议,有时我们也会直接拒绝,因为显然社区中一半的人反对这个提议时,它就不可能实现。
我们对Go语言的向后兼容性非常重视。我们希望尽可能确保老的Go程序能够在现代Go语言中继续运行。 这往往是一个决定性的因素。正如你所说,很多人来自其他语言,他们会说:“我想要某个特性。”Go已经存在了足够长的时间,以至于我们可以说:“是的,我们四年前讨论过这个问题,并且已经考虑了所有的论点。如果你有新的观点,我们很乐意听取,但如果只是重复之前的想法,很抱歉,我们已经考虑过了。”
Host: 当然,我认为这是有价值的。很多人现在非常担心冒犯他人。如果有人花时间编写了一份规范,并提出了一个功能建议,而我们的回应是:“我们四年前讨论过这个问题。”有些人可能会感到失望,但实际上,这表明他们没有做足够的功课,因为他们没有查看我们是否已经讨论过这个问题。
我经常谈到社区的优缺点。在开源领域,社区建设无疑是好事,但同时也可能形成回音室效应。
比如,你会遇到一些对某个事物非常执着的人。举个例子,如果你有一些在C++领域的人,他们对C++非常执着。但由于某种原因,也许他们的公司正在采用Kubernetes或其他容器化工具,而Go语言会是构建解决方案的一个绝佳候选项,因此他们不得不学习Go语言。他们开始学Go,然后觉得:“这太糟糕了,和C++比起来我讨厌这个,但我需要在它的框架下工作,所以让我试着成为其中的一部分。”但他们是带着负面的心态进入的。你是否看到过很多人仅仅因为Go语言与其他语言不同而“批评”它?或者大多数进入社区的人都是出于对Go语言的热情,并只希望看到语言变得更好?
回音室效应(Echo Chamber Effect)指的是一种社交或传播现象,其中个体倾向于接触与自己观点相符的信息,导致对不同观点的忽视或排斥。这种现象在社交媒体和网络环境中尤为明显,用户往往只会关注与自己意见一致的内容,从而形成一种“回音室”,使得自己的观点不断被强化。
主要特点:
- 信息选择性:个体主动选择与自己观点相符的信息源。
- 排斥异议:对不同或相反观点的信息持有抵触态度,可能会屏蔽或忽略这些信息。
- 观点极化:随着时间的推移,个体的观点可能变得更加极端,导致社会分裂。
影响:
- 社会分化:不同群体之间的隔阂加深,减少了对话和理解。
- 谣言传播:错误信息在回音室中容易传播,因为缺乏多元的信息来源来进行事实核查。
- 情绪反应:在高度极化的环境中,个体的情绪反应可能更为强烈,导致对话的困难。
应对策略:
- 多元信息源:主动接触不同观点的信息,扩展视野。
- 批判性思维:培养批判性思维能力,评估信息的可靠性。
- 促进对话:鼓励开放的讨论和交流,增进理解。
Ian: 我们两种情况都见过。是的,确实有人会进来批评这门语言,但这并不常见;当然也有发生的时候。我们只是尽量礼貌地回应:“我们从没声称Go是解决一切问题的答案,恰恰相反。最初,Go是一个实验,是我们希望能让人们思考这些想法的另一种尝试。”所以当有人进来说:“Go和C++比起来太糟糕了。”我们的回应可能是:“你喜欢C++,也没关系。”
Host: 我觉得这是一个公平的回应。
我认为还有一点是人们看到了Go的潜力,但他们并不完全理解。你提到了一些目标,例如你希望它非常高效、非常简单。如果你只是开始往里添加各种东西,那么它会变得臃肿,库会变得过大,它们可能不会以最有效的方式编写,因为你必须考虑向后兼容性。你会陷入一个困境,我为此道歉,你最终可能会“糟蹋”这门语言。作为一名语言设计者,这是你最不愿意看到的情况。
我想到的一个例子是C++,它基本上已经添加了几乎所有现代功能,但这花了30年的时间。想想看,这真的很疯狂。我认识一些在微软工作的人,他们非常活跃在C++的委员会中。每次我们讨论时,他们总是觉得这非常具有挑战性,因为你必须总是假设有人会使用一种25年没有动过的语言,你不能破坏他们的代码。
尤其是当你在编写非常大型的系统时,比如Docker或Kubernetes,或任何可以扩展这些系统的工具,最后你最不希望发生的事情是你为了向语言中添加某个东西而破坏了向后兼容性,导致整个系统崩溃。显然,你永远不会遇到这种情况,因为作为一名语言设计者,你必须考虑到这一点,但在添加新特性时,总是有最坏的可能性。这不仅仅适用于语言设计,任何系统的构建都是如此。即使你在系统中添加新功能,你也很可能会破坏很多东西。
Ian: 这种情况确实会发生,而且确实很难预料。人们会以意想不到的方式使用你的代码。在谷歌,我们有一个叫做“希拉姆定律”(Hiram’s Law)的说法,这个名字来自谷歌的一位员工,但这个术语现在已经流传开来。希拉姆定律基本上是说,你系统的任何行为,无论是否记录在案,都是你必须保留的特性。当然,微软对此非常了解,他们确保所有这些古老的Windows程序仍然可以运行,即使它们依赖于旧系统中的一些错误。
Host: 我总是觉得这很有趣。我曾经是一名顾问,曾有一个客户非常依赖Windows的低级API。他们遇到了一个问题,所以我们进去调查,问他们做了什么。他们回答:“我们只安装了一个安全补丁。”结果是,有人在代码中添加了一个捕获异常的代码,用来帮助解决一个API问题,而客户的程序正好依赖于这个API在特定情况下抛出异常,这完全破坏了他们的工具。他们完全不知道为什么会这样,只是因为他们安装了一个补丁。
想想这真是太疯狂了。这个客户是一家非常知名的公司,而这个工具也是一个非常著名的工具。它依赖于Windows API在特定情况下崩溃,这既滑稽又可怕。
在我们的对话快要结束时,我想谈谈Go的未来。你说过,Go语言并不是一门非常古老的语言,尽管它内部已经存在了大约15年。现在它已经公开发布了,但你认为这门语言的未来是什么?目前,很多人认为它是顶级语言之一。你认为Go语言会继续得到更多的采用吗?还是说它总会有一个适合它的特定领域,但不会扩展到其他领域?你的看法是什么?
Ian: 我觉得很有趣,我愿意相信它会继续被更多人采用。我认为它是一门通用语言,并没有特别的细分领域。我认为它不会在那些性能绝对至关重要的领域发挥作用,那不是Go的强项。我也不认为它会在深度嵌入式系统或内核编程中发挥很大的作用。但我认为它会用于通用编程,对于网络服务器、数据库、容器化(显然),以及任何系统服务,它都是非常有用的。它也适合用于脚本编写和工具开发。所以,我认为它仍然有一个非常光明的未来。
我不确定我们是否会对这门语言进行大的改变,也许我们会继续对语言进行一些微调。但就目前而言,我不认为会有大的变化。我认为我们更多的是在让库变得更强大,使用起来更容易,并适应未来的新技术。但我对Go的未来持乐观态度。
Host: 至少根据我的经验,我认为Go是一门值得考虑的语言。正如你所说,也许Go不需要统治世界,但它有着非常非常重要的地位,而且这个领域相当广泛。我认为将来会有一个时刻,人们会选择Go而不是传统的解决方案,因为它的简单性。
我有一个朋友在西雅图的一家公司工作,他们的所有后端都是用C++编写的。他们开始思考:“我们在C++中没有做任何荒谬的事情,我们不需要语言的所有特性。我们真的需要C++吗?”他们正在考虑使用Go来开发一些较小的系统作为概念验证。我认为这是一个很好的例子。如果你希望代码容易理解,并且能够快速编写,而不必担心各种复杂的事情,那么Go是一个很好的选择。
当然,也有一些情况,比如你不想写太多的样板代码。就像你提到的,在Go语言中,你会写很多代码,这就是它的特点。如果你不喜欢这样做,Go可能并不是最合适的选择。
Ian: 你提到的,我注意到多年来,C++是一门非常棒的语言,我也依然非常喜欢它。但在编写复杂的C++程序时,人们往往会陷入关于如何最有效地使用这门语言的复杂讨论中。这是完全可以理解的,因为C++确实是一门非常优秀的高性能编程语言。然而,这种讨论往往围绕着如何在语言中最好的表达问题以及如何最好的使用语言特性展开。这就是在C++中经常发生的事情,而这不是我们希望在Go语言中看到的。我们希望在Go中,人们能够清晰地表达问题,而不必纠结于如何使用这门语言。我们希望Go成为一种让人们专注于解决问题而不是工具本身的语言。
Host: 我认为这是一个很好的观点。你希望工具能够让位于解决方案本身。如果你在构建一个解决方案,最后你真的不想做的事情是为了实现而在代码实现上做各种权衡。实现应该是相当直接的。
非常感谢你今天能来和我们聊天。我总是会问我们的嘉宾一个问题,如果你用一个词来形容开源,你会用哪个词?
Ian: 一个词吗?
Host: 你可以作弊,用两到三个词。
Ian: “慷慨”。这很重要,正如我之前提到的“站在巨人的肩膀上”,慷慨与此非常契合。
Host: 再次感谢你今天的时间,也感谢所有收听《咖啡与开源》节目的听众,祝大家度过愉快的一天。