
Niklaus Wirth(尼克劳斯·维尔特,瑞士,1934 年生)在 程序设计语言设计与结构化程序 领域的位置,很少有人能给出准确坐标。他设计了两门至今仍在用的语言,并提出了一条被反复验证的规律——语言每加一个特性,程序员的负担就加一分——这句话后来直接催生了 Python 与 Go。
一、问题一:如何让机器翻译一门高级语言——以及为什么编译器必须是递归下降
Niklaus Wirth 的起点要回到 瑞士巴塞尔。当时 生于瑞士巴塞尔;他在苏黎世联邦理工学院取得电子工程学位,随后赴加州大学伯克利分校取得博士学位,导师是生成式语言的先驱之一;他在伯克利期间接触到了当时最新的计算机与编译技术——这段经历日后被 Niklaus Wirth 反复提起,成为其方法论的原点。
他的学术起点在工程而非数学,这让他从一开始就把语言当作「人与机器之间的接口」而不是形式对象来研究。
他在伯克利期间参与开发了 ALGOL W,这段经历让他同时理解了「语言设计」与「编译器实现」两侧的问题——这在他的后续工作中反复出现。
他早年在苏黎世工学院任教时,那里的学生群体构成了他语言工作的第一块试验田:他要面对的不是抽象的语法问题,而是初学者在真实编程课程中会遇到的具体障碍。
他曾明确说过,他设计语言的目标从来不是表达所有可能的程序,而是让常见的程序容易被正确地写出来。
他 1934 年生于瑞士,家族中有工程与数学的双重背景。
二、1960-1970 年代:结构化程序与「先定义后使用」
1966 年的 发表《结构化程序设计》并系统提出结构化程序设计的三条基本结构 是 Niklaus Wirth 的分水岭。核心主张是:任何复杂程序都应由顺序、条件与循环三种基本结构构成,从而在结构上消除 goto 带来的控制流混乱,让程序可以被逐步证明与逐步理解,这一点后来被整个 程序设计语言设计与结构化程序 领域反复引用,而 结构化程序设计成为此后三十年软件工程教育的基础框架,并直接塑造了此后所有主流编程语言的控制流设计。
他与 Hoare 共同提出的三条基本结构(顺序、选择、迭代),其学术意义在于证明了「只要限制控制流的表达形式,程序的理解与验证就能被结构化地组织」。
结构化程序设计与 goto 的论战在 1960 年代末达到高潮,他与 Dijkstra 的观点一致:goto 并非语法上不可用,而是在表达层面破坏了程序的结构。
他提出的「先定义后使用」与「单入口单出口」这两条具体原则,在当时比抽象的论点更有效地推动了工业界代码风格的确立。
这一时期他还提出了一项影响深远的观点:程序设计教育应当培养「系统性地分解问题」的能力,而不是记住某种语言的语法——这个主张贯穿他后来的教学与教材工作。
他与 Hoare 共同提出的三条基本结构(顺序、选择、迭代),其学术意义在于证明了只要限制控制流的表达形式,程序的理解与验证就能被结构化地组织。
他在 1966 年前后发表《结构化程序设计》,系统提出三条基本结构。
三、1970 年代:Pascal 与 Modula——为教学而生的语言
1976 年的 设计 Pascal 语言,随后设计 Modula 与 Modula-2,作为教学与系统实现语言 是 Niklaus Wirth 的分水岭。核心设计取舍是:宁可放弃某些表达能力,也要让语言的规则足够少、足够正交,从而让初学者能在一学期内掌握,并让编译器能给出清晰的错误信息,这一点后来被整个 程序设计语言设计与结构化程序 领域反复引用,而 Pascal 成为二十世纪最广泛使用的教学语言,Modula-2 的模块化机制则是后来 Ada 包(package)与 Java 包(package)的直接前身。
Pascal 的设计目标明确写在语言报告里:它应当足够小以便完整教完,同时足够正交以便让人一次只学一样东西——这与当时 ALGOL 68 的庞大设计形成鲜明对比。
Pascal 最有影响力的遗产其实不是它在教学中的成功,而是它塑造了「结构化程序」这一整代编程范式,并通过 C 等语言传到了更广的生态里。
Modula 引入的模块(module)机制,把一组相关的类型、过程与数据封装成一个可独立编译、可替换的单元,这个概念在工业界被反复独立发明出来。
Modula-2 的并发构造(协程、进程、信号量)来自他与 Hoare 合作提出的通信顺序进程模型,这套模型后来成为 CSP 与 Go 并发模型的思想源头。
他始终在语言与编译器之间同时工作——他设计的语言往往同时伴随一个他亲自实现的编译器,这个习惯让他对语言实现的代价有第一手的判断。
Modula 引入的模块机制,把一组相关的类型、过程与数据封装成一个可独立编译、可替换的单元,这个概念在工业界被反复独立发明出来。
他在 1976 年前后设计 Pascal 语言,随后推出 Modula 与 Modula-2。
四、1984 年:Ada 与「国防项目的语言」
1980 年前后,学界的主流判断仍偏保守。在 1960-1970 年代,业界普遍认为语言特性越丰富表达能力越强,Pascal 式的精简设计被视为保守甚至落后,但 Niklaus Wirth 选择 他的反问是:如果一门语言每个特性都要被学习、记住并正确使用,那么特性的边际收益是递减的,而负担却是累加的,代价是 这个主张让他在语言设计圈中长期被视为不够激进,而 ALGOL 68 等更庞大的设计在同期获得了更多关注与资源。
他受美国国防部之邀起草的这份报告,通常被认为是软件工程史上最重要的语言设计文档之一,因为它把「语言应该有什么」变成了可讨论、可验证的清单。
报告里提出的几条原则在三十年后依然成立:语言应当内建并发支持而非依赖库;应当有强类型检查;错误处理应当是语言的一部分;并且语言的设计者必须给出可执行的实现来验证其可行性。
他没有参与 Ada 的最终实现,但他提出的「一个语言必须有一个实现来证明它可行」这一主张,客观上推动了后续许多语言都以「先写原型编译器」的方式起步。
在这次合作之后,他的注意力从语言本身转向了语言实现与编译技术,这一转向在 1980 年代催生了 Lilith 工作站与其配套的 Modula-2 编译环境。
他参与了美国国防部一份语言需求报告的起草,把「一门语言必须具备什么」变成可讨论、可验证的清单。
他在 1980 年前后参与起草美国国防部的语言需求报告,列出「一门语言必须具备什么」。
五、问题二:图形界面需要一台自己的机器——Lilith 与编译技术
1980 年,Niklaus Wirth 进入 苏黎世联邦理工学院。这一步不是履历跳跃,而是问题换轨:在 苏黎世联邦理工学院从事 Pascal 与 Modula 语言设计的阶段 里 Niklaus Wirth 关心的是 如何让一门语言既足够强大又能在一学期内被初学者完整掌握,到了 苏黎世联邦理工学院,问题变成 如何把语言设计与编译器实现当作一件事来做,而不是各自独立。
Lilith 的规格极其克制:单用户、内存 2MB 量级、要求全系统可重编译以保证一致性——这套约束反而成就了它在研究与教学上的巨大影响力。
他强调「可重编译性」作为一种系统质量指标:若系统不能用同一套源码从零构建出来,那么它的任何修改都可能引入不可见的偏差,这一原则至今仍被大型系统团队引用。
Lilith 的开发同时验证了一个观念:语言与工具链应当由同一批人设计,因为只有这样才能避免抽象层之间的裂缝。
从 Lilith 演化出的 Oberon 系统采用了极简的设计哲学——去除继承、去除并发原语,以换取极小的内核与极高的可移植性,这个取舍在学术上备受推崇。
他在 1980 年前后主导 Lilith 工作站与编译环境的建设。
六、他验证过的那条定律:一条被时间反复验证的设计定律
1984 年的 ACM 图灵奖(1984 年,颁给 Pascal、Modula、Oberon 系列工作)、ACM 软件系统奖与 SIGPLAN 终身成就奖 之后,Niklaus Wirth 把主要精力投到 撰写多本影响深远的程序设计教材,并持续撰文批评软件工业中的复杂度累积 上。对 程序设计语言设计与结构化程序 领域而言,「语言特性越少越好」这一主张被 Python、Go、Rust 等当代语言的设计者反复引用。
他晚年最著名的批评是针对软件工业本身:他认为行业倾向于用不断叠加的框架与抽象来解决旧问题,而这些新抽象又成为下一代问题的根源——这是一个自我加速的复杂度循环。
他与 Hoare 合作提出的「循环不变量」与「前置条件/后置条件」记法,为形式化方法提供了此后所有主流工具都采用的规格语言骨架。
他编写的程序设计教材影响了多代工程师,特点是每一章都配有一个从零写起的完整程序,而不是伪代码——这与他对「可理解性优先」的一贯主张一致。
他晚年提出的一个著名论断是:软件工程中真正的挑战不是「如何建造」,而是「如何决定不建造什么」——这个判断在今天的开源与大模型生态中显得格外准确。
参考来源
- Niklaus Wirth,《Algorithms + Data Structures = Programs》, 1976
- Niklaus Wirth,《Structured Programming》, 1972(ACM Computing Surveys)
- Niklaus Wirth,《The Pascal Language》与《Systematic Program Design》
- Niklaus Wirth 起草的《Requirements for a Programming Language》国防部报告,1977
- Lilith 与 Oberon 系统的技术报告与设计说明
- ACM 1984 年度图灵奖官方授奖说明