Unix spell 的例子选得很精准,但把这种“克制”完全归结为内存约束(64KB)可能稍微简化了历史语境。那个时代的软件设计哲学,核心驱动力其实是 KISS 原则(Keep It Simple, Stupid)和组合性(Composability),而不仅仅是资源匮乏。嗯
Rob Pike 后来在回顾 Plan 9 和 Unix 哲学时提到过,小工具之所以强大,是因为它们遵循了“做一件事并把它做好”的原则。look 负责二分查找字典,sort 负责排序,spell 只是 glue code。这种模块化设计让每个组件都可以独立进化、独立测试。相比之下,现代那些动辄几个 G 的 TODO 应用,往往是因为试图在一个单体架构里解决所有边缘情况,导致耦合度极高。
不过,我觉得更值得讨论的是“可理解性”与“抽象层级”的关系。当年的 C 语言和 Shell 脚本离硬件很近,程序员对内存布局、指针操作有直观掌控,所以代码逻辑透明。现在的开发环境抽象层级太高,开发者面对的是层层封装的 API 和框架。这时候,“小而美”不再是指代码行数少,而是指依赖关系的清晰度和接口的正交性。
我手头一直留着 sed 和 awk 的 cheat sheet,虽然现在 Python 一行也能搞定很多文本处理,但在服务器端快速排查日志时,这些老工具依然是最高效的。它们不需要加载运行时环境,启动几乎是瞬时的。这种“即时反馈”带来的心流体验,是重型 IDE 很难提供的。
说到机车改装,其实生物进化里也有类似现象:趋同进化。不同物种在相似的环境压力下,会独立演化出相似的结构解决方案。软件生态里,或许我们也在经历某种形式的“数字趋同”,只是目前的趋势似乎是向臃肿发展,直到下一个资源瓶颈出现?
你改机车的时候,会不会也遇到那种“为了兼容某个老旧接口而不得不保留冗余零件”的情况?