论代码的意图
摘要
作者认为,阅读和编写代码就像讲故事,意图通过显式和隐式的方式传达。他们讨论了在阅读代码时理解作者意图的重要性,并使用了 C++ auto、Python 类型注解和公司编码策略等示例。
<p><a href="https://lobste.rs/s/vb29tc/on_intent_code">评论</a></p>
查看缓存全文
缓存时间: 2026/07/04 16:43
# 关于意图
来源:https://why.degree/on-intent/
我之前曾论证过,编写代码就像写故事。现在,我要更进一步:阅读代码也像读故事。反过来,可以将代码视为一种传达意图的方式,无论是显式的(例如通过注释),还是隐式的(例如通过数据结构)。一方面,代码编写者必须考虑从其他程序员的角度来看,自己的代码读起来如何。另一方面,每一行代码背后的意图,可能只有在读者深入抽象层级之后才能理解。因此,编码是一门艺术。与其他任何艺术一样,美丑皆在观者眼中。
LifeOverflow 的这段视频(https://youtu.be/Q5kIdpPIVuY)关于德国刑法中与黑客相关的部分,在我心中埋下了一粒种子:在与计算机交互时,我如何表达意图?想象一下,技术顾问需要向律师——进而向法官——解释为什么某些命令在某些语境下是恶意的,这令人着迷。打个比方,这就像解释为什么在某些场景下使用刀具是恶意的,而在其他场景下则是善意的。一个好的顾问-律师搭档会在每个案件中找到不同的要素,并将天平倾向期望的方向,例如:通过识别目标用户、他们本应访问哪些信息、受限制数据的保护级别,以及获取这些数据所需的努力程度。反过来,我开始意识到自己是如何阅读代码的:通过追问作者想要达成什么目的。以 C++ 中“几乎总是用 auto”这条准则为例。其想法是使用 auto 来避免用无关类型塞满代码。关于这一点已有诸多讨论,但核心是:除了那些显而易见的情况外,大多数情况下可以忽略这条规则,因为为了写代码速度而牺牲阅读清晰度,长远来看是有害的。
此外,要完全把握意图,有必要考虑并非直接与技术相关的方面,例如历史和社会因素。最近在工作中遇到一个例子:我选择了一个预处理器字符串而不是 C/C++ 字符串,因为它与代码的其余部分更匹配,而且我无法改动其他所有代码。另一个类似的例子是关于 Python 中的类型,以及较旧的代码很可能不包含任何类型注解,因为 PEP 484 直到最近才获得大量支持和扩展——PEP 673。最后一个例子:我曾在一家禁止注释的公司工作,他们认为注释“没有增加任何价值,开发者应该把时间花在让代码更明确上”。所有这些例子都表明,程序员在开发软件时必须权衡那些不那么显性的需求,而工具的功能并不是最终的制约因素。
从阅读的角度看,理解一个新的代码库,关键在于识别意图的章节和子章节——即一个类或函数背后的主要功能,以及当需要完整细节时,每一行代码背后的含义。高效做到这一点的窍门是:先理解整个故事,然后观察不同的情节和线索是如何相互关联的。举一个部分相关的例子:我主要工作的遗留代码库,理解它花了我几个月时间。原因之一是有将近一百万行代码;原因之二是我的目标不是快速完成,而是深入研究。由于进入了一个新领域,我发现代码背后的意图通常需要解释。在这种情况下,代码已经变成了一种达到目的的手段:我研究的不是代码,而是它的用例。考虑到这一点,测试驱动开发的一个好处是:通过先写测试再写代码,测试的是意图而非实现细节。类似的论点也适用于调试,程序员检查自己的原始想法在多大程度上转化成了代码。由此可知,错误可以分为几类:一类是由于意图翻译不准确、遗漏了细节而产生的;另一类则是实现上的不足,比如想法是有的,但具体的命令和指令带有隐含的副作用和历史背景。我认为没有哪一类比另一类更容易修复,因为两者都提出了棘手的案例。
总而言之,我给出了几个理由,说明编码背后统一的概念是意图。通过这个镜头来看待程序,我们就能获得一种新的理解方式,适用于任何规模、任何编程语言的代码库。读者在新环境中跟随的是意图,而编写者则是在给定一组需求下试图达成意图。在包罗万象的语境下,可能还不够,但它是最大、也最具可迁移性的基石。
相似文章
代码审查需要认真阅读代码
一篇开发者博客文章反对在不阅读 AI 生成代码的情况下直接将其部署到生产环境,强调代码审查具有至关重要的作用:分散责任、降低巴士因子风险,以及让团队成员保持对代码库的了解。
始终追溯
本文探讨了通过版本控制追溯代码演变来阅读和理解代码的策略,重点强调了 `git blame` 的使用以及理解作者视角的重要性。
编码即思考:为何我仍坚持手写代码
作者认为手写代码对于培养批判性思维和解决问题的能力至关重要,并警告不要过度依赖AI编程工具。
@geoffreylitt: 热论:我认为理解我们的代理编写的代码仍然很重要!在这个超长帖子中(基于我的 A…
Geoffrey Litt 认为,开发者理解 AI 代理编写的代码仍然很重要,并分享了高效理解这类代码的想法。
@mattpocockuk: “是否应该阅读代码”的争论很愚蠢,因为真正的决定不是二元的,而是一个尺度:1. 阅读每一行……
Matt Pocock 认为,代码审查中是否阅读代码的决定并非二元,而是一个范围,他列出了从阅读每一行到让模型处理一切的七个参与级别。