用过度思考、范围蔓延和结构化 diff 把项目搞砸
文章摘要
Kevin Lynagh 在这期 newsletter 里复盘了一种他自己反复犯的”项目自毁模式”:当一个想法冒出来时,他往往不是直接动手,而是开始大量调研既有方案、阅读论文、对比工具,结果在”研究 + 反复重新评估”的循环里耗尽精力,最终项目无果而终。与之形成鲜明对照的是那些被他迅速完成、并感到满意的项目——它们的共同点是”成功标准”在一开始就被极其清晰地定义,从而避免了完美主义的扩张。
文章的核心案例是结构化 diff(structural diff):Kevin 想要在 Emacs 里得到一个比传统行级 diff 更聪明的代码对比工具。他花了 4 个小时翻看学术论文、PhD 级别的复杂讨论以及竞品(Difftastic、Gumtree、Mergiraf、德国公司做的 Semanticdiff 等),却没产出一行代码。他注意到 Difftastic 在重命名 struct 时仍会错配名字,认为各个工具的算法都各有取舍——比如某位作者就抱怨 “context-sensitive keywords 一直是麻烦的来源”。意识到这一点后,他给自己重新约束:“我只是想给我自己在 Emacs 里有一个更顺手的 diff 体验,那应该 4 小时就能搞定,我自己写就行。”
他还提出一个有趣的观察——“范围蔓延守恒律”:在用 LLM 帮忙构建一个 Finda 风格的 Emacs 文件搜索器时,他通过 Nucleo 库引入了 anchor 之类的高级特性,事后才发现这些特性自己根本用不上。LLM 让代码写得更快,但同样把不必要的功能也写得更多,最终他不得不丢弃几个小时的实现工作。他怀疑 LLM 辅助开发是否真带来净增益,仍未下定论。
作为对比,他举了一个干净利落的项目:和朋友一起用边角料木材在周末做出一个厨房隔板。成功标准只有一句话——”和朋友一起做木工”,而不是”造一个完美的隔板”,所以即便中途反复迭代、用了不那么理想的材料,也能毫无负担地完工。
文章的具体行动方案是放下学术级抽象:先用 Treesitter + Rust 写一个最小的实体抽取框架,先用贪心匹配算法,先把结果输出到命令行——之后才考虑 Emacs 集成与多语言支持。最后他甚至打趣:”我可能就在自己家里偷偷用,不去尝试把它商业化。”
核心结论是:清晰的成功标准 + 拥抱”那个 20 岁、懵懵懂懂、就是会动手”的自己,远比无止境的研究更能让项目落地。事后回看会觉得当时的方案”明显有缺陷”,但仍然比一直 contemplate 强得多。
HN 评论精华
- Newsletter ≠ 博客文章:多位评论者提醒读者,这是一篇 newsletter 而非聚焦于单一论点的博客,所以会有多条线索交织——这并不是结构混乱,而是文体不同。
- 博士研究的普遍体验:一位在大学讲席工作的网友写道:”到这一步,你已经证明你聪明、博学;现在宇宙想看你能不能把开了头的事完成。”——精准描绘了延毕博士的痛点与本文同构。
- 编程速度守恒律:一条高赞评论提出:”任何编程速度的提升都会被同等增加的多余特性、兔子洞与岔路抵消。”在 LLM 时代尤其成立。
- 完美主义即拖延的另一面:完美主义者并不只是把事情做到极致,更常见的形态是”因为达不到完美就干脆放弃,没有任何进展”。
- 目标必须能压缩成一句话:”如果我没法把目标压缩成一句话,那我还没准备好动手,我准备好的只是漫无目的地游荡。”
- 结构化 diff 的隐形陷阱:最不易察觉的失败模式是”在脑子里比较两套想象中的架构”——大脑感觉一直很忙,但 commit 是零、决策也是零。
- Better is good:增量改进会复利累积,因为”任何新东西第一次都不会完美”。要敢于先交付一个不完美但可用的版本。
- 判断力依赖于领域经验:何时该深度规划、何时该立刻迭代,不存在统一答案;这种”判断”本身就是经验积累的产物。