Towards Understandable Software
Towards Understandable Software: Why programming sucks and how to fix it
迈向可理解的软件:为什么编程很糟糕,以及如何解决它
2026-03-07 · 13 min · #computing
Programming sucks. Code sucks. It’s hard to read, hard to test, and hard to maintain. Only a handful of people can understand any particular software project. These are major problems. I’m here to explain how we can fix them. 编程很糟糕。代码很糟糕。它难以阅读、难以测试且难以维护。只有少数人能真正理解某个特定的软件项目。这些都是主要问题。我在这里要解释我们该如何解决它们。
LLMs aren’t the Model
大语言模型并非终极方案
Large Language Models (LLMs) are becoming an important part of industry software development. Even experts with years of experience are using LLM agents to test, debug, and even write code. Now that many LLMs are capable of integrating with their environments, some of their logistical problems have been mitigated. 大语言模型(LLMs)正成为工业软件开发的重要组成部分。即使是拥有多年经验的专家,也在使用 LLM 智能体来测试、调试甚至编写代码。随着许多 LLM 能够与开发环境集成,它们的一些逻辑问题已经得到了缓解。
Non-programmers have also turned to LLMs. Programming can be unapproachable. Many people have no clue where to start and, even if they did, have no desire to learn the fine details of the syntax and libraries of any particular language. I regularly see people with little programming knowledge use LLMs to write them anything from simple personal scripts to tools for processing scientific data. 非程序员也转向了 LLM。编程可能让人望而却步。许多人根本不知道从哪里开始,即使知道,也不想去学习特定语言的语法和库的细节。我经常看到几乎没有编程知识的人使用 LLM 来编写各种程序,从简单的个人脚本到处理科学数据的工具。
I don’t believe this is the result of LLMs being incredible at programming. Almost everyone in the field has seen the results of a session of “vibecoding.” Even if the tests pass, the resulting code is usually atrocious. No, I believe programmers and non-programmers alike have turned to LLMs because programming sucks. There are so many conflicting software stacks, endless boilerplate, and annoying libraries. The work of the average software developer has been reduced to gluing libraries together rather than developing interesting code. 我不认为这是因为 LLM 在编程方面有多么出色。业内几乎每个人都见过“凭感觉编程”(vibecoding)的结果。即使测试通过,生成的代码通常也惨不忍睹。不,我认为无论是程序员还是非程序员转向 LLM,都是因为编程本身很糟糕。有太多的软件栈相互冲突,无休止的样板代码,以及令人烦恼的库。普通软件开发者的工作已经沦为拼凑库,而不是开发有趣的代码。
But the fact that programming sucks doesn’t make LLMs suck any less. The major problems with them persist. They still are environmentally destructive, fundamentally based on stolen code, produce inconsistent code, and instill dependency. Overall, LLMs make programming worse than it has been before, despite their promise. We deserve better than current programming paradigms, but we also deserve better than LLMs. 但编程很糟糕这一事实,并不能让 LLM 显得不那么糟糕。它们的主要问题依然存在。它们仍然破坏环境,从根本上基于窃取的代码,产生不一致的代码,并灌输依赖性。总的来说,尽管 LLM 带来了承诺,但它们让编程变得比以前更糟。我们值得拥有比当前编程范式更好的东西,但我们也值得拥有比 LLM 更好的东西。
We Can do Better
我们可以做得更好
We don’t have to give up automation if we give up LLMs. We don’t have to give up high levels of abstraction if we give up LLMs. We don’t have to give up human-friendly interfaces if we give up LLMs. The benefits promised by LLMs may not outweigh their costs, but we don’t have to give up those benefits. We can have predictable, high-level, testable systems that make software more maintainable. We don’t even have to give up using natural language to communicate with machines. We just have to take a different approach. 如果我们放弃 LLM,并不意味着要放弃自动化。我们不必放弃高层抽象,也不必放弃对人类友好的界面。LLM 所承诺的好处可能无法抵消其成本,但我们不必放弃这些好处。我们可以拥有可预测、高层级、可测试的系统,使软件更易于维护。我们甚至不必放弃使用自然语言与机器交流。我们只需要采取不同的方法。
Instead of tackling the problem of writing code, we should tackle the software stack underlying the code. Instead of making it easier to generate endless amounts of code, we should eliminate the need to write it at all. We should embrace the layers of abstraction that have led us to higher and higher level languages. When the urge to automate one layer of abstraction emerges, we should instead abstract it away. The prevalence of LLMs in programming has shown us we need a different approach to programming. The urge to automate the process of writing code has shown us we need to abstract the need to write code at all. We need another layer of abstraction that allows us to think about software even to the ways humans—not computers—naturally think. 与其解决“编写代码”的问题,不如解决代码底层的软件栈。与其让生成海量代码变得更容易,不如彻底消除编写代码的需求。我们应该拥抱那些引领我们走向更高层级语言的抽象层。当出现自动化某个抽象层的冲动时,我们应该将其抽象化。LLM 在编程中的普及表明我们需要一种不同的编程方法。自动化编写代码过程的冲动表明,我们需要从根本上抽象掉“编写代码”的需求。我们需要另一个抽象层,让我们能够以人类(而非计算机)自然思考的方式来思考软件。
Document the Yak
记录“牦牛”
The first and most important step of making software understandable is documentation. If we want software to be understandable to other humans, the least we can do is explain it to them. Programmers already know that documentation is important, but for the most part we see it as something to tack onto the code afterward. We write the code, and then maybe add doc-comments to explain what outwardly facing functions do. If our users are lucky, we’ll even write usage examples. 让软件变得可理解,第一步也是最重要的一步就是文档。如果我们希望软件能被其他人理解,我们至少应该向他们解释清楚。程序员们已经知道文档很重要,但在大多数情况下,我们将其视为代码写完后的附加工作。我们先写代码,然后可能添加一些文档注释来解释外部函数的功能。如果用户幸运的话,我们甚至会写一些使用示例。
I propose we flip this. Instead of writing the code first and tacking on documentation, we write the documentation first and tack on the code. We tell humans what our program does and then we tell the computer what it is supposed to do. This is a concept known as Literate Programming. Imagine this: instead of reading other people’s code and then trying to parse their intentions from it, you read the documentation to understand their intentions and then you read the code. You no longer have to strain yourself trying to understand what someone wrote for another audience (the machine). They’ve already explained it for you. 我建议颠倒这个过程。与其先写代码再补文档,不如先写文档再附上代码。我们先告诉人类程序的功能,然后再告诉计算机它应该做什么。这就是所谓的“文学编程”(Literate Programming)。想象一下:你不再需要阅读别人的代码并试图从中解析他们的意图,而是通过阅读文档来理解他们的意图,然后再阅读代码。你不再需要费力地去理解某人为另一个受众(机器)写的东西。他们已经为你解释过了。
The best implementation of this I’m aware of is the Entangled bi-directional tangler. A tangler extracts code from your documentation and distributes it across the appropriate source code files. It’s bidirectionality means you can use it to write code embedded in documentation, but then also edit that code normally which it then propagates back into the code blocks in the documentation. This allows programmers to use existing tooling for testing, refactoring, and code formatting without special support for literate programming. And it’s fast. Tanglers add little overhead to your build system, especially compared to a compiler. 我所知的最佳实现是 Entangled 双向缠结器(bi-directional tangler)。缠结器从文档中提取代码,并将其分发到相应的源文件中。它的双向性意味着你可以编写嵌入在文档中的代码,同时也可以正常编辑这些代码,然后它会将更改同步回文档中的代码块。这使得程序员可以使用现有的工具进行测试、重构和代码格式化,而无需对文学编程进行特殊支持。而且它很快。与编译器相比,缠结器对构建系统的开销微乎其微。
We should embrace this approach and document the entirety of our software stack, from the firmware that boots our computers to the Web applications we use to connect with our communities. This would make every aspect of software more accessible to those who use and develop it. Go ahead and shave the yak, but also document it. This approach doesn’t directly solve the ways that programming sucks. It still involves code and all the messiness that entails, but it makes that sucky code more comprehensible. It replaces LLMs in one area: understanding other people’s code. 我们应该拥抱这种方法,记录我们整个软件栈,从启动计算机的固件到我们用来连接社区的 Web 应用程序。这将使软件的各个方面对使用者和开发者来说都更易于访问。去“剃牦牛”(shave the yak,指解决琐碎问题)吧,但也要把它记录下来。这种方法并不能直接解决编程糟糕的问题。它仍然涉及代码以及随之而来的所有混乱,但它让那些糟糕的代码变得更易于理解。它在理解他人代码这一领域取代了 LLM。
Abolish Code
废除代码
But we can go further. Not only can we document our code—we can destroy it. Code is a concept from a bygone era. We were forced to work with it because we used to interact with computers through terminals. We used a keyboard to input instructions into a computer, which then ran interpreted and ran those instructions. There’s no reason we have… 但我们可以走得更远。我们不仅可以记录代码,还可以摧毁它。代码是一个过时时代的概念。我们被迫使用它,是因为我们过去通过终端与计算机交互。我们使用键盘向计算机输入指令,然后计算机解释并运行这些指令。没有理由我们必须……