Stroustrup法则(2024)
摘要
Bjarne Stroustrup的法则指出:对于新特性,程序员更偏好显式语法,但一旦该特性被确立,他们就更倾向于简洁表示法。本文探讨了 Rust 和 Python 中的示例,并讨论了这对语言设计和教学的影响。
暂无内容
查看缓存全文
缓存时间: 2026/06/30 21:39
# Stroustrup 法则
来源:https://buttondown.com/hillelwayne/archive/stroustrups-rule
刚结束两周的工作坊,累*垮了*,所以这篇会写得轻松一些。
### 光明节促销
*编程逻辑*一书在光明节期间打特价!如果你不是犹太人,截止日期是1月2日。
点击此处(https://leanpub.com/logic/c/hannukah-presents)以四折购买。
## Stroustrup 法则
我第一次看到**Stroustrup 法则**是在这个已失效的网页(https://web.archive.org/web/20240914141601/https:/www.thefeedbackloop.xyz/stroustrups-rule-and-layering-over-time/)上:
> 关于语法设计,我最喜欢的一个见解来自 Bjarne Stroustrup 的 C++ 回顾(https://learn.microsoft.com/en-us/shows/lang-next-2014/keynote)¹(https://buttondown.com/hillelwayne/archive/stroustrups-rule#fn:timing):
> - 对于新特性,人们坚持使用**显眼**的显式语法。
> - 对于成熟特性,人们想要简洁的记法。
博主以 Rust 中的可选项类型为例。最初,使用可选项类型来存储错误对程序员来说很新鲜,所以传递错误的语法非常显式:
``
let file = match File::open("file.txt") {
Ok(file) => file,
Err(err) => { return err; }
}
``
当人们熟悉之后,Rust 添加了 `try!` 宏来减少样板代码,最后又引入了 `?` 运算符(https://github.com/rust-lang/rfcs/blob/master/text/0243-trait-based-exception-handling.md)来进一步简化错误处理。
我认为这是心智模型发展(http://teachtogether.tech/en/index.html#s:models)的一个特例:当某个特性对你而言是新的,你还没有内在的心智模型,所以需要所有能获得的显式信息。一旦你熟悉了,显式语法就成了视觉干扰,反而阻碍你快速解析信息。
(我喜欢的一个例子:`user_id` 和 `user_identifier` 哪个更显式?有经验的程序员更喜欢哪个?)
有趣的是,往往*是同一个人*在光谱的两端。初学者需要显式语法,而成为专家后,他们更喜欢简洁的记法。
这条法则也适用于整个社区。在一种语言的早期,所有人都是初学者。随着时间的推移,专家与初学者的比例发生变化,这就导致社区更关注“对专家友好”的特性,比如更简洁的语法。
这可能让初学者更难学习这门语言。Python 中关于“海象”赋值运算符(https://peps.python.org/pep-0572/)曾有过很多争议:
``
# 不使用 walrus
val = dict.get(key) # 键不存在则返回 `None`
if val:
print(val)
# 使用 walrus
if val := dict.get(key):
print(val)
``
专家支持它,因为它使代码更优雅;教师和初学者反对它,因为它让语言更难学。显式语法 vs 简洁记法。
这是否会导致语言随时间变得臃肿?
### 在教学中的应用
我发现,在教授语言工作坊时,我不得不主动与 Stroustrup 法则对抗。那些对我*自己*最易读的简洁记法对初学者来说并不好,他们需要的是让我觉得刺眼的显式语法。
一个很好的例子是 TLA+ 中的类型不变量。假设你有一组工人,每个工人有一个计数器。下面有两种方式来表示每个工人的计数器都是非负整数:
``
\* 不好
\A w \in Workers: counter[w] >= 0
\* 好
counter \in [Workers -> Nat]
``
第一种方式字面上测试了对于每个工人,`counter[w]` 是否为非负。第二种方式测试 `counter` 映射整体是否属于合适的“函数集”——即所有从工人到自然数的函数。
函数集方式更简洁、更优雅,TLA+ 专家也更喜欢它。但我教的是“不好”的那种,因为对初学者来说更容易理解。
相似文章
Syntax with Purpose in a Programming Language
这篇文章探讨了编程语言语法设计的重要性,认为语法应准确反映语言的计算模型和心智模型,而非为了熟悉感或简洁性随意拼凑。作者通过分析OCaml、Lisp/Clojure和JavaScript的语法设计,并介绍自己设计的语言Saul,强调了统一性和语义一致性。
引用 Mitchell Hashimoto
Mitchell Hashimoto 评论编程语言日益增强的可替代性,以 Bun 从 Zig 重写为 Rust 为例,表明语言已不再是锁定效应的来源。
迈向可理解的软件
本文批判了当前的编程实践和对大语言模型的依赖,反而主张通过更好的抽象、文档和软件栈来使代码更易于理解和维护。
静态类型与铲子(2026)
作者认为,2010年代静态类型编程的复兴归功于改进的类型系统(例如 TypeScript、Haskell、Rust),这些系统提供了可空类型处理、和类型以及类型推断,与 Java 和 C++98 等早期语言中糟糕的静态类型形成对比。
2026 年的 Zig 与 Rust
本文在 2026 年的背景下对比了 Zig 和 Rust,认为编程代理通过自动化生成 Rust 代码,削弱了 Zig 在人机交互体验上的优势。