标签 C 下的文章

Go考古:创始人亲述Go语言的“创世纪”

本文永久链接 – https://tonybai.com/2025/07/03/meet-the-go-team-2012

大家好,我是Tony Bai。

2012 年,Google I/O 大会的舞台上,一个刚刚发布 1.0 版本的编程语言团队,正襟危坐。他们面对着全球开发者的审视和提问,这其中,就有三位图灵奖得主级别的传奇人物:Ken Thompson、Rob Pike 和 Robert Griesemer。

那一年,Go 1.0 的发布,是一个历史性的里程碑。它意味着一个承诺“向后兼容、稳定可靠”的 Go 语言,正式诞生。

今天,就让我们扮演一次“Go 语言考古学家”,拂去时间的尘埃,回到那个被称为“创世纪”的时刻,重温 Go Team 核心成员们的亲口讲述,探寻这门语言最纯粹的初心和设计哲学。

我们为何创造 Go?—— “厌倦了等待 C++ 编译”

在访谈中,当被问及创造 Go 的初衷时,Rob Pike 给出了一个近乎“玩笑”却又无比真实的答案:

“我们厌倦了等待 C++ 的编译。”

他生动地描绘了当时在 Google 内部的日常:为了构建一个巨大的 C++ 二进制文件,团队成员不得不在庞大的计算集群上等待超过一个小时。

更令人抓狂的是失控的依赖管理。Rob Pike 提到,他的同事 Mike Burrows(Chubby 的作者)在一次漫长的编译中发现,一个他从未听说过的、与项目毫无关系的头文件,竟然被重复编译了 37,000 次

“当你用 ifdef 宏来保护依赖时,你最终得到的就是一个极其稠密的、做了太多无用功的依赖之巢。” Rob Pike 总结道。

这个巨大的痛点,催生了 Go 最核心的设计目标之一:从语言层面,彻底解决依赖问题。

  • 清晰的依赖图: Go 的导入路径直接明了。
  • 拒绝无用功: 编译器会拒绝未被使用的导入。
  • 高效的编译链: 设计上保证了“编译包 A 不应再重新编译包 C(如果 A->B->C)”。一旦包 B 被编译,它就携带了关于 C 的所有必要信息。

而对于另一位创始人、C 语言和 Unix 的共同发明者 Ken Thompson 来说,促使他下定决心的“临门一脚”则更为直接和幽默。当被问及为何对 Go 如此热情时,他言简意赅:

“当我试图去读 C++0x(即 C++11)的标准草案时,我就下定决心了。”

全场爆笑。在一门日趋复杂的巨型语言面前,三位大师不约而同地选择了回归简单

Go 的“魔法”时刻 —— 那些改变编程方式的设计

Go 的简洁并非简陋。在这次访谈中,创始人们也分享了那些让他们自己都感到惊喜和自豪的“魔法”设计。

Slices (切片):Ken Thompson 的神来之笔

Rob Pike 回忆道,团队曾为了“数组”到底该如何工作而苦恼了整整一年。他们既想要静态检查的固定长度数组,又渴望某种形式的可变长度数组。在无数次的挣扎后,有一天,Ken Thompson 带着 slice 的想法走进办公室。

“起初我们并不确定这是不是正确答案,” Rob Pike 说,“但一旦我们开始使用它,一切都变得显而易见。” 一个简单而优雅的设计,完美地解决了这个旷日持久的难题。

Interfaces (接口):Rob Pike 的挚爱

对于 Rob Pike 而言,接口是他认为 Go 中最强大的特性。

“接口深刻地改变了我对软件开发的思考方式。一个程序由这些可以轻松‘粘合’在一起的东西组成,这种感觉太棒了。它改变了软件被构建的方式。”

Go 的接口是隐式实现的。这种非侵入式的设计,让组件之间的耦合度降至最低,极大地促进了代码的解耦和可组合性。

Packages (包):看似显然,实则艰难

今天我们觉得理所当然的 Go 包机制——一个包可以由多个文件组成,包内全局变量可以任意顺序声明——在当时也是经过了无数次辩论才最终成型的。

“它看起来似乎是显而易见的,但要弄清楚这一点真的非常困难。” Rob Pike 感叹道。这种“松散”的包设计,极大地简化了代码组织和重构的难度。

有所为,有所不为 —— Go 的设计权衡

当被问及如何看待 D 语言等其他试图改进 C++ 的语言时,Robert Griesemer 阐述了 Go 截然不同的设计哲学:

“我的印象是,D 语言会像 C++ 一样不断成长。而在 Go 中,我们试图采取完全相反的方式:尽可能地移除东西,将其简化到骨架,只保留你构建一切所需的绝对最小值。”

他相信,如果这些小组件是正交且能良好协作的,最终得到的东西会比拥有大量相互掣肘的特性的语言更强大。

这种“少即是多”的哲学,体现在 Go 对许多“流行特性”的刻意“缺失”上。当被问及“最庆幸 Go 缺失了什么特性”时,团队成员提到了:

  • 类型继承体系 (Type Hierarchy)
  • 可选参数 (Optional Arguments)
  • 列表推导式 (List Comprehensions)
  • 三元运算符

Rob Pike 指出,在 Java 或 C++ 中,你通常从设计类型继承树开始。这项工作耗时耗力,一旦发现设计有误,回头修改的成本极高。Go 通过移除类型继承,让程序在演进过程中更易于调整和适应。

为了凸显 Go 的简洁与 C++ 的复杂之间的对比,Rob Pike 更是转述了当时未能到场的 Russ Cox 的一句玩笑话,它为 Go 的哲学做了最好的注脚:
“C++ 的风格指南里条条框框,而 Go 的风格指南第一句或许应该是:你可以使用这门语言的全部。”

回望 2012 的“预言” —— 那些已实现和仍在路上的事

考古的乐趣,在于用今天的视角去审视昨天的预言。在 2012 年,Go Team 对未来的展望,如今看来既有惊人的远见,也留下了些许历史的印记。

  • 对 Go 1.1 的精准预言: 他们当时预测 1.1 版本将专注于性能提升、GC 改进、调度器优化和对更多操作系统的支持。这与后来 Go 1.x 系列的演进路径完全吻合。
  • 对 Go 2.0 的务实态度: 团队明确表示“Go 2 遥遥无期”,Go 2 的新想法将来自于使用 Go 1 中发现的真实需求。这个务实的态度至今仍在指导着 Go 的发展。
  • 最大的“失误”? 当被问及此,团队坦诚地提到了 nil 指针(Tony Hoare 的“十亿美元的错误”),以及循环变量的作用域问题。这些话题,至今仍在社区中被热烈讨论。
  • 未解的难题与渴望: Rob Pike 当时多次提到,他们非常想实现但还没找到完美方案的“网络化的 Channel (netchan)”,以及对一个真正的“抢占式调度器”的渴望。这些难题,在后来的岁月里,通过不同的方式被逐步探索和解决。

小结:回到源头,理解初心

穿越时空,回到 Go 语言的“创世纪”现场,我们听到的不是高深莫测的理论,而是一群务实的工程师,为了解决自己在日常工作中遇到的真实、具体的痛点,而进行的一场充满智慧、权衡与热情的创造。

他们对简洁的极致追求,对工程效率的深刻理解,以及对“少即是多”的坚定信念,共同塑造了今天我们所热爱的 Go 语言。

理解这段历史,就是理解 Go 的灵魂。

参考资料链接:https://www.youtube.com/watch?v=sln-gJaURzk


你的Go技能,是否也卡在了“熟练”到“精通”的瓶颈期?

  • 想写出更地道、更健壮的Go代码,却总在细节上踩坑?
  • 渴望提升软件设计能力,驾驭复杂Go项目却缺乏章法?
  • 想打造生产级的Go服务,却在工程化实践中屡屡受挫?

继《Go语言第一课》后,我的《Go语言进阶课》终于在极客时间与大家见面了!

我的全新极客时间专栏 《Tony Bai·Go语言进阶课》就是为这样的你量身打造!30+讲硬核内容,带你夯实语法认知,提升设计思维,锻造工程实践能力,更有实战项目串讲。

目标只有一个:助你完成从“Go熟练工”到“Go专家”的蜕变! 现在就加入,让你的Go技能再上一个新台阶!


商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。

当一切皆可用Python:Go这样的通用语言与DSL的未来价值何在?

本文永久链接 – https://tonybai.com/2025/06/19/language-design-in-the-era-of-llm

大家好,我是Tony Bai。

大型语言模型 (LLM) 的浪潮正以前所未有的速度和深度席卷软件开发领域。从代码生成、Bug 修复到文档撰写,AI 似乎正成为每一位开发者身边无所不能的“副驾驶”。在这股浪潮中,一个略显“刺耳”但又无法回避的论调开始浮现,正如一篇引人深思的博文《Programming Language Design in the Era of LLMs: A Return to Mediocrity?》中所指出的那样:“一切都更容易用 Python 实现 (Everything is Easier in Python)”——当然,这里指的是在 LLM 的强力辅助下。

这并非危言耸听。文章中展示的图表(来源于论文 “Knowledge Transfer from High-Resource to Low-Resource Programming Languages for Code LLMs“)清晰地揭示了一个趋势:LLM 在那些训练数据量巨大的“高资源”语言(如 Python, JavaScript, Java, C# 等)上,代码生成和任务解决的效能显著高于像 Go、Rust 这样的“低资源”语言:

如果 LLM 能够如此轻松地用 Python(或其他高资源语言)根据自然语言需求生成大部分“胶水代码”甚至核心逻辑,那么我们不禁要问:

  • 精心设计和构建领域特定语言 (DSL) 的价值还剩下多少?当消除冗余、封装领域知识这些 DSL 的核心优势,似乎可以被 LLM+通用语言轻易取代时,DSL 的未来是否会因此停滞?
  • 对于像 Go 这样以简洁、高效、工程化著称的通用语言,当其在 LLM 训练数据中的“声量”不及 Python 时,它的核心竞争力又将面临怎样的挑战与机遇?

今天,我们就来聊聊在 LLM 时代,DSL 和像 Go 这样的通用语言,其未来的价值究竟何在。

DSL 的黄昏?当 LLM 成为“万能代码生成器”

领域特定语言 (DSL) 的核心价值在于“专为特定领域而生”。通过精心设计的语法和语义,DSL 能够:

  • 提升表达力: 让领域专家或开发者能用更接近自然语言或领域术语的方式描述问题。
  • 消除样板代码: 将领域内的通用模式和“常识性规则”编码到语言自身。
  • 降低认知负荷: 开发者可以更专注于问题的“有趣”部分,而非底层实现细节。
  • 减少错误面: 通过语言层面的约束,使得编写出不正确的程序变得更加困难。

文章中那个视频游戏对话的例子就非常典型:从繁琐的 API 调用序列

# example code for a VN
character.draw("alice", character.LEFT, 0.1)
character.draw("bob", character.RIGHT, 0.1)
character.say("alice", "hello there!")
character.say("bob", "hi!")
character.state("alice", "sad")
character.say("alice", "did you hear the news?")

到简洁的 DSL 描述

# example DSL for dialog
[ alice @ left in 0.1, bob @right in 0.1  ]
alice: hello there!
bob: hi!
alice[sad]: did you hear the news?...

DSL 的优势一目了然。

然而,LLM 的出现,似乎正在侵蚀 DSL 的这些传统护城河。当开发者可以用自然语言向 Copilot 或 ChatGPT 描述“我想要一个能让 Alice 和 Bob 在屏幕两侧对话的场景”,并且 LLM 能够直接生成 Python 或 JavaScript 代码来实现这个功能时,我们不禁要问:为什么还要费心去学习、设计、构建和推广一个全新的 DSL 呢?

这里隐含的“机会成本”的问题非常现实:

  • DSL 的学习与生态位:使用一个“小众”的 DSL,意味着开发者可能要放弃使用 LLM 在主流语言上生成代码的巨大便利。LLM 在小众 DSL 上的表现(如果未经专门微调)几乎可以预见会非常糟糕。
  • DSL 的构建成本:设计和实现一个高质量的 DSL 本身就需要巨大的投入。在 LLM 时代,这个投入的“性价比”似乎正在下降。

这引发了一个令人担忧的趋势:DSL 的发展是否会因此停滞不前?语言设计的多样性是否会因此受到冲击,最终导致“人人皆写 Python (在 LLM 辅助下)”的局面?

Go 语言:在 LLM 时代的“低资源”挑战与独特优势

Go语言虽然在全球拥有数百万开发者,并且在云原生、后端开发等领域占据主导地位,但在 LLM 的训练数据占比上,相较于 Python、JavaScript 等拥有更长历史和更广泛应用场景(尤其是 Web 前端、数据科学等产生大量开源代码的领域)的语言,仍然处于“低资源”状态。

这意味着,LLM 在直接生成高质量、复杂 Go 代码方面的能力,目前可能还无法与它在 Python 等语言上的表现相媲美。 这对 Go 社区和开发者来说,既是挑战,也是反思和寻求新机遇的契机。

挑战:

  • 如果 LLM 生成 Go 代码的效率和质量暂时落后,可能会降低新手或寻求快速原型验证的开发者选择 Go 的意愿。
  • Go 社区可能需要投入更多精力来构建 LLM 友好的工具、库和高质量的训练数据。

然而,Go 语言的独特优势在 LLM 时代或许会更加凸显:

  • 简洁性与明确性对 LLM 的“友好”:
    • Go 语言语法精炼,关键字少,没有复杂的继承和隐式转换。这种“所见即所得”的特性,可能使得 LLM 更容易理解 Go 代码的结构和语义。
    • Go 的强类型系统和明确的错误处理机制 (if err != nil),虽然在手动编码时有时显得冗余,但在 LLM 生成或分析代码时,这些明确的信号可能有助于 LLM 生成更健壮、更易于验证的代码。
  • 强大的标准库与工程化特性:
    • Go 丰富的标准库覆盖了网络、并发、编解码等常见场景。LLM 在生成 Go 代码时,可以更多地依赖这些经过充分测试和优化的标准组件,减少对第三方库的复杂依赖。
    • Go 内置的测试、性能分析、代码格式化等工具,以及其对模块化的良好支持,有助于对 LLM 生成的代码进行有效的质量控制和集成。
  • 并发模型与性能优势的不可替代性:
    • Go 的 Goroutine 和 Channel 提供的轻量级并发模型,在构建高并发网络服务和分布式系统方面具有独特优势。这部分逻辑的复杂性和对性能的极致要求,可能难以完全由 LLM 在 Python 等语言中通过简单生成来完美复制。
    • Go 编译后的静态二进制文件和高效的执行性能,在许多后端和基础设施场景中依然是硬核需求。
  • Go 作为“基础设施”语言的潜力:
    • LLM 本身就需要强大的基础设施来训练和运行。Go 在构建这些大规模、高并发的 AI 基础设施方面,已经扮演了重要角色(如 Ollama 等项目)。
    • Go 的简洁性和安全性,也使其成为定义和执行 AI Agent 行为、编排复杂 AI 工作流的理想语言。

LLM 时代,语言设计(DSL 与通用语言)的破局之路

面对大型语言模型(LLM)带来的挑战,编程语言的设计(无论是领域特定语言(DSL)还是通用语言如 Go)并非只能被动应对。学术界正在探索一些富有前景的新方向,旨在实现语言设计与 LLM 的协同进化,而非零和博弈。

首先,有研究提出教会 LLM 理解 DSL 的方法,核心思路是利用 LLM 擅长的语言(如 Python 的受限子集)来表达核心逻辑。由于 LLM 对特定 DSL 的理解和生成能力有限,开发者可以设计工具或方法,将这些 Python 表达式“提升”或自动翻译到目标 DSL 中。这一思路启示未来的 DSL 设计者应考虑为其语言提供一个 LLM 友好的“语义映射层”,例如用 Python 或其他高资源语言来描述其核心概念和操作。

其次,在 DSL 中弥合“形式化”与“非形式化”的鸿沟也是一个重要方向。开发者在编写复杂系统内核时,往往需要精确控制每一行代码,此时 LLM 的帮助有限。然而,在编写不常用的“一次性”脚本时,LLM 能够根据自然语言描述生成“胶水代码”,使得开发者只需关注核心的“有趣”部分。因此,未来的 DSL 设计可以探索如何无缝集成“非形式化”自然语言描述,作为规范、注释,甚至直接融入代码中。与此同时,是否可以从 DSL 的类型系统或静态分析结果中,自动生成高质量的自然语言规范,反过来帮助 LLM 更好地理解和生成 DSL 代码,值得深入研究。

最后,面向 LLM 辅助验证的语言设计也成为一种趋势。研究者们不再满足于 LLM 生成“能运行”的代码,而是期望 LLM 能生成带有形式化规约(specifications)的代码,并利用验证语言(如 Dafny、Boogie)来证明这些代码的正确性。这一趋势对 DSL 和通用语言(如 Go)的设计提出了新要求,开发者需要考虑如何更好地支持“规约即代码”和“验证即开发”的模式。例如,Go 语言的强类型和接口设计,为形式化验证提供了一定的基础,未来的改进可以在此基础上进一步发展。

通过以上几个方向的探索,编程语言设计有望与 LLM 实现更为紧密的协同进化,推动软件开发的进步和创新。

小结:挑战之下,价值重塑

LLM 的崛起,无疑对整个编程语言生态带来了深刻的冲击和前所未有的挑战。那种“学会一门语言,用好一个框架,就能高枕无忧”的时代可能正在远去。

“一切皆可用 Python (在 LLM 辅助下)”的论调,虽然略显夸张,但也点出了一个事实:对于那些仅仅是为了减少样板代码、提供简单抽象的 DSL,或者在表达力和生态丰富度上不及 Python 的通用语言,其生存空间确实受到了挤压。

然而,这并不意味着语言设计本身会走向“平庸化”或消亡。相反,LLM 可能会迫使我们重新思考编程语言的核心价值:

  • 对于 DSL,未来可能需要更高的“门槛”——它们必须提供真正深刻的领域洞察和远超通用语言的表达效率与安全性,才能证明其存在的必要性。同时,与 LLM 的协同将是关键。
  • 对于像 Go 这样的通用语言,其价值将更多地体现在那些难以被 LLM 轻易复制的领域:极致的工程效率、经过实战检验的并发模型、强大的底层控制能力、以及构建大规模、高可靠系统的综合实力。Go 需要继续打磨其核心优势,并积极拥抱 AI,成为 AI 时代不可或缺的基石。

最终,技术的浪潮会淘汰掉不适应变化的,也会催生出新的、更强大的生命体。对于我们开发者而言,保持学习的热情,理解不同工具的本质和边界,拥抱变化,或许才是应对这个“AI 定义一切”时代的不二法门。

你认为 LLM 会如何改变你使用的编程语言?Go 和 DSL 的未来将走向何方?欢迎在评论区留下你的真知灼见!


精进有道,更上层楼

极客时间《Go语言进阶课》上架刚好一个月,受到了各位读者的热烈欢迎和反馈。在这里感谢大家的支持。目前我们已经完成了课程模块一『语法强化篇』的 13 讲,为你系统突破 Go 语言的语法认知瓶颈,打下坚实基础。

现在,我们即将进入模块二『设计先行篇』,这不仅包括 API 设计,更涵盖了项目布局、包设计、并发设计、接口设计、错误处理设计等构建高质量 Go 代码的关键要素。

这门进阶课程,是我多年 Go 实战经验和深度思考的结晶,旨在帮助你突破瓶颈,从“会用 Go”迈向“精通 Go”,真正驾驭 Go 语言,编写出更优雅、
更高效、更可靠的生产级代码!

扫描下方二维码,立即开启你的 Go 语言进阶之旅!

感谢阅读!

如果这篇文章让你对AI时代的DSL和通用语言设计和未来有了新的认识,请帮忙转发,让更多朋友一起学习和进步!


商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。如有需求,请扫描下方公众号二维码,与我私信联系。

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言进阶课 Go语言精进之路1 Go语言精进之路2 Go语言第一课 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats