标签 DSL 下的文章

Martin Fowler最新洞察:LLM 不止是“更高”的抽象,它正在改变编程的“本质”!

本文永久链接 – https://tonybai.com/2025/06/26/non-deterministic-abstraction

大家好,我是Tony Bai。

在软件开发领域,Martin Fowler 的名字几乎等同于思想的灯塔。他的每一篇文章、每一次演讲,都能为我们揭示行业发展的深层脉络。最近,Fowler 大师又发布了一篇简短但引人深思的博文——《LLMs bring new nature of abstraction》,再次精准地捕捉到了一个正在发生的、可能颠覆我们认知和工作方式的巨大变革。

Fowler 认为,大型语言模型(LLM)的出现,对软件开发的影响,堪比从汇编语言到首批高级编程语言(HLLs)的飞跃。但关键在于,LLM 带来的不仅仅是又一个“更高层次”的抽象,它正在从根本上改变编程的“本质”——迫使我们思考,用“非确定性工具”进行编程究竟意味着什么。

在这篇文章中,我们就来简单解读一下。

从“确定性”的阶梯到“非确定性”的岔路

回顾编程语言的发展史,我们一直在追求更高层次的抽象,以提升生产力、降低复杂度:

  • 汇编语言 vs. 机器指令: 汇编让我们用助记符替代了 0 和 1,但仍需关注特定机器的寄存器和指令集。
  • 高级语言 (HLLs) vs. 汇编: Fortran、COBOL 等早期 HLLs 让我们能用语句、条件、循环来思考,而不用关心数据如何在寄存器间移动。Fowler 回忆道,他用 Fortran IV 编程时,虽然有诸多限制(如 IF 没有 ELSE,整数变量名必须以 I-N 开头),但这已经是巨大的进步。
  • 现代语言、框架、DSL vs. 早期 HLLs: Ruby、Go、Python 等现代语言,以及各种框架和领域特定语言(DSL),进一步提升了抽象层次。我们现在可以本能地将函数作为数据传递,使用丰富的库和模式,而不用从头编写大量底层代码。

Fowler 指出,尽管这些发展极大地提升了抽象层次和生产力,但它们并没有从根本上改变“编程的性质”。我们仍然是在与机器进行一种“确定性”的对话:给定相同的输入和代码,我们期望得到相同的输出。错误(Bug)也是可复现的。

然而,LLM 的介入,打破了这一基本假设。

Fowler 写道:“用提示词与机器对话,其差异之大,犹如 Ruby 之于 Fortran,Fortran 之于汇编”。

更重要的是,这不仅仅是抽象层次的巨大飞跃。当 Fowler 用 Fortran 写一个函数,他可以编译一百次,结果中的 Bug 依然是那个 Bug。但 LLM 引入的是一种“非确定性”的抽象 (non-deterministic abstraction)

这意味着,即使我们把精心设计的 Prompt 存储在 Git 中,也不能保证每次运行都会得到完全相同的行为。正如他的同事 Birgitta Böckeler 精辟总结的那样:

我们并非仅仅在抽象层级上“向上”移动,我们同时也在“横向”移入非确定性的领域。

Fowler 文章中的配图非常形象地展示了这一点:传统的编程语言、编译器、字节码是一条清晰的、自上而下的抽象路径;而模型/DSL、代码生成器、低代码、框架是其上的不同抽象层次。自然语言(通过 LLM)则像一条从旁边切入的、直接通往“半结构化/接近人类思维”的道路,这条路本身就带有模糊和不确定性。

“非确定性”编程时代的挑战与启示

这种“非确定性”的本质,对我们 Gopher,乃至所有软件开发者,都带来了前所未有的挑战和需要重新思考的问题:

  1. 版本控制与可复现性: 当 Prompt 不能保证结果一致时,我们如何管理和版本化我们的“AI辅助代码”?如何确保开发、测试、生产环境的一致性,或者至少是可接受的差异性?仅仅版本化 Prompt 可能不够,我们还需要版本化模型、参数(如 temperature)甚至是一些关键的种子(seed)吗?
  2. 测试与调试: 如何测试一个输出不完全固定的“组件”?传统的单元测试、集成测试方法是否依然有效?我们可能需要引入新的测试策略,例如基于属性的测试、对输出结果的统计验证、或者更侧重于行为和意图的验证。当 LLM 生成的代码出现问题,调试的难度是否会指数级增加?
  3. 可靠性与契约: 在一个包含非确定性AI组件的系统中,如何定义和保证整体的可靠性?服务间的“契约”又该如何描述和强制执行?
  4. 思维模式的转变: 我们习惯了对代码的精确控制,追求逻辑的严密和行为的可预测。现在,我们可能需要学会与“模糊”和“概率”共存,从“指令下达者”转变为“意图沟通者”和“结果筛选者”。

这对我们 Gopher 意味着什么?

Go 语言以其明确性、强类型、简洁的并发模型以及相对可预测的行为,深受开发者喜爱。当我们尝试将 LLM 融入 Go 的生态和开发流程时,这些“非确定性”的特性会带来新的思考:

  • AI 生成 Go 代码: 当我们使用 LLM 生成 Go 代码片段、单元测试,甚至整个模块时,如何确保生成的代码符合 Go 的最佳实践、是高效且安全的?如何对生成的代码进行有效的审查和集成?
  • 用 Go 构建与 LLM 交互的工具/Agent: 如果我们用 Go 开发与 LLM 交互的后端服务或智能体(Agent),我们需要在架构设计上充分考虑 LLM 的非确定性,设计更鲁棒的错误处理、重试机制,以及对 LLM 输出结果的验证和筛选逻辑。
  • 利用 LLM 理解复杂 Go 系统: LLM 或许能帮助我们理解遗留的复杂 Go 代码库,但其解释的准确性和一致性也需要我们审慎评估。

Fowler 在文末表达了他对这一变革的兴奋之情:“这种改变是戏剧性的,也让我颇为兴奋。我相信我会为一些失去的东西感到悲伤,但我们也将获得一些我们中很少有人能理解的东西。”

小结:拥抱不确定,探索新大陆

Martin Fowler 的这篇文章,为我们揭示了 LLM 时代编程范式可能发生的深刻转变。它不再仅仅是工具的进化,更是与机器协作方式的本质性变革。

作为 Gopher,作为软件工程师,我们需要开始认真思考这种“非确定性”带来的影响,积极探索与之共存、甚至利用其特性创造价值的新方法。这无疑是一个充满挑战但也充满机遇的新大陆。

你如何看待 Fowler 的这个观点?你认为 LLM 带来的“非确定性”会对你的日常开发工作产生哪些具体影响?欢迎在评论区分享你的看法!


你的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