2019 年的 1024,我写过一篇《如何成为更好的程序猿》。七年后的今天,想再讨论一个与编程有关的话题。

在中文技术社区,有不少讨论「编程的本质」的文章,喜欢引用一个经典公式:

程序 = 算法 + 数据结构

但我一直对这个解释有所保留。我更认同曾经在一本书中看到的另一个观点:

编程是对客观世界建模的过程。

直到最近几年 AI Coding 的兴起,我又重新想起了这个话题。

程序的构成,等于编程的本质吗?

「程序 = 算法 + 数据结构」出自计算机科学家 Niklaus Wirth 于 1976 年出版的著作《Algorithms + Data Structures = Programs》。

首先需要澄清一个容易被忽略的细节:原书标题中的 Programs 是「程序」,而不是「编程」(Programming)。

程序是产物,编程是创造程序的活动。这显然是两个不同的概念。

其次,即使我们接受这个公式,也不能直接将其理解为对编程本质的定义。

举个物理学的例子。爱因斯坦著名的质能关系:

E₀ = mc²

它描述的是物体的静止能量与质量之间的关系。但我们显然不能据此认为,能量的本质就是质量乘以光速的平方。

一个公式能够揭示重要的物理关系,并不意味着它已经穷尽了某个概念的全部内涵。

同样,Wirth 的公式高度概括了程序设计中的两个重要要素,但这并不等于回答了「编程的本质是什么」。

问题不在于 Wirth 的原书或公式,而在于我们是否恰当地理解和引用了它。把一个描述程序构成的公式,直接当作对编程本质的定义,我认为并不恰当。

算法和数据结构,本身不就是建模吗?

这是我更想讨论的问题。

先看数据结构。

我们熟悉的 Tree、Graph、Array,本质上是什么?

Tree 是对层次关系的抽象,Graph 是对实体及其关系的抽象,Array 则是对有序集合及其索引关系的抽象。

例如,一个企业的组织架构,我们可以用 Tree 来表示;但如果员工同时参与多个项目,存在复杂的跨部门协作关系,Graph 可能是更合适的选择。

为什么?

因为我们首先需要理解这个组织如何运作,然后选择一种能够恰当表达其结构和关系的数据模型。

数据结构,本身就是对结构和关系的建模。

那么算法呢?

以排序算法为例。

我们首先定义一组元素,定义元素之间的比较关系,再确定希望得到什么样的顺序。接下来,设计一套计算过程,让这些元素按照预期完成排列。

无论是冒泡排序、快速排序还是归并排序,都可以理解为针对同一个问题建立的不同计算过程模型。

算法,本身就是对过程和行为的建模。

这样看来,算法和数据结构并不是与建模并列的两个概念,而是建模在计算机科学中的具体表现。

数据结构描述事物如何组织,算法描述事物如何变化。

因此,我依然倾向于多年前的那个观点:

编程是对客观世界建模的过程。

当然,这里的客观世界不一定局限于我们日常接触的物理世界,也可以包括经济活动、社会关系,以及数学和计算机科学中的抽象问题。

我们通过观察、抽象、形式化和验证,建立能够描述和处理问题的模型,再将其转化为计算机可以执行的程序。

如果一切都是建模,这个定义还有意义吗?

这个观点其实面临一个很自然的质疑。

如果编程的本质是建模,那么物理学家不也在建模吗?经济学家不也在建模吗?工程师、建筑师,甚至社会学家,不都在进行某种形式的建模吗?

如果我们用建模来定义编程,似乎什么都能解释,但也因此失去了编程自身的特殊性。

这个质疑是成立的。

当一个定义能够覆盖越来越多的活动,它对某一类活动的区分能力确实可能下降。

但我想反过来问一个问题:

我们为什么一定要通过「本质」,来区分不同的职业?

我们讨论的是编程的本质,而不是程序员与经济学家有什么区别。

如果编程、经济学和物理学在更深的层次上共享同一种认知活动——通过抽象和建模理解世界——那么这种共性本身,难道不值得我们关注吗?

换句话说,建模或许不是编程独有的特征,但它可能是编程与其他科学、工程活动共同的认知基础。

这并不能在严格的哲学意义上证明建模就是编程唯一的本质,但至少提供了一个比算法和数据结构更上位的理解视角。

而 AI 的出现,让这个原本偏向哲学层面的讨论,突然具有了非常现实的意义。

从建模到 Ontology

说到建模,我想顺便提一个概念:Ontology。

Ontology 在哲学中通常译为「本体论」,研究存在及其基本范畴。在计算机科学中,它通常指对某个领域的概念、关系及约束进行明确的形式化描述。

例如,我们要设计一个商业系统。

什么是商品?什么是库存?商品与库存之间是什么关系?什么叫库存预留?库存预留与库存扣减又有什么区别?

这些问题看起来简单,但不同的理解,可能导致完全不同的系统设计。

比如,当我们说「为积分商城预留20件商品」时,这20件商品究竟已经从普通库存中扣除了,还是只为积分商城设置了一个销售配额?

在没有明确这些概念之前,讨论使用什么数据库、采用什么并发控制算法,可能都为时过早。

这也是 Ontology 给我的启发:在思考如何让计算机处理一个世界之前,我们首先需要弄清楚,自己究竟在描述一个怎样的世界。

当然,Ontology 并不等同于建模的全部,但它提供了一个非常有价值的视角:我们如何定义事物,如何理解事物之间的关系,以及如何将这些理解转化为明确的形式化表达。

AI 时代,建模者也可以成为程序的创造者

现在,让我们回到前面那个质疑。

如果经济学家、物理学家和程序员都在建模,那么编程的特殊性在哪里?

在过去,这个问题其实不太重要。

一个经济学家即使建立了很好的经济模型,如果希望将它转化为可运行的软件,通常还需要学习编程语言,或者寻找程序员帮助实现。

他可能非常了解经济主体之间的关系、市场运行的机制、变量之间的相互影响,却未必知道如何用 Python 编写程序。

于是,建模和程序实现之间,存在一道明显的技术门槛。

但 AI 正在改变这个局面。

今天,一个经济学家可以直接向 AI 描述自己的模型,让 AI 帮助他实现计算逻辑、构建数据结构、编写程序,甚至生成可视化界面。

他可能从来没有系统学习过数据结构和算法,也不熟悉传统的软件开发流程,但这并不妨碍他通过 AI 将自己的模型转化为可运行的程序。

当然,复杂的软件工程仍然需要专业技术能力。但至少,亲自掌握编程语言,已经不再是创造程序的绝对前提。

AI 正在大幅降低从模型到程序的实现门槛。

这时候,我们再回头看前面那个关于「解释力下降」的质疑,就会发现一个有趣的变化。

正因为建模不是程序员独有的能力,AI 才有可能让更多领域的人直接参与程序创造。

过去,我们习惯于把编程视为程序员的专业技能,很大程度上是因为实现程序需要掌握一套专门的技术。

但如果这套技术的门槛正在被 AI 降低,那么编程与其他学科之间的边界,也可能随之发生变化。

一个经济学家通过 AI 构建经济模拟系统,一个物理学家通过 AI 编写实验分析程序,一个设计师通过 AI 创造交互应用。

他们不一定是传统意义上的程序员,但他们同样在创造程序。

也许我们过去对编程的理解,过于受限于编程语言和程序员这个职业本身。

程序员或许应该接触一点哲学

写到这里,我反而觉得,在 AI 时代,程序员或许应该尝试接触一点哲学。

过去,我们花大量时间学习编程语言、数据结构、算法、设计模式和各种技术框架。这些知识当然仍然重要,但 AI 已经能够承担越来越多的代码实现工作。

当写出代码不再是最困难的事情,我们是否应该花更多时间思考,自己究竟在解决什么问题?

我们如何认识一个问题?如何确定哪些概念是重要的?如何进行抽象?如何判断一种模型是否合理?又如何在不同的模型之间作出选择?

这些问题并不是计算机科学所独有的。

哲学中的本体论、认识论和逻辑学,早就在不同层面讨论类似的问题。

我并不是建议程序员都去系统学习哲学。只是觉得,当 AI 不断降低技术实现的门槛时,我们或许可以暂时把目光从下一门编程语言、下一个框架上移开,尝试接触一些更基础的思想。

毕竟,算法和数据结构可以帮助我们构造程序,但如何理解世界、如何建立模型,可能是更值得长期思考的问题。

回到多年前那个关于编程本质的讨论,我依然坚持当时的观点:

编程是对客观世界建模的过程。

AI 并没有改变编程的本质,而是让编程的本质变得更加清晰。

过去,我们需要亲自编写代码,将对世界的理解转化为程序。现在,AI 正在帮助越来越多的人完成这个过程。

也许 AI 时代真正值得关注的,不只是程序员会不会被取代,而是:

当越来越多具备建模能力的人都可以创造程序时,我们是否需要重新理解「编程」这件事?