Skip to content
Published on

Scarf 为何恋恋不舍地告别用了 7 年的 Haskell — 语言选择的真正成本

分享
Authors

引言 — 离开一门喜欢的语言意味着什么

"我换语言了"这类文章,往往会变成对那门语言口诛笔伐的场合。然而 2026 年 7 月,Scarf 创始人 Avi Press 写的这篇文章却是完全相反的基调。光是标题就说,他是"恋恋不舍地(reluctantly)"离开了 Haskell。他是 16 年的 Haskell 老粉,Scarf 也在生产环境跑了 7 年 Haskell。用他自己的话说,这类文章他很少写 — 他更喜欢做点东西、再把它推广出去,而不是当一个爱批评的人。

这篇文章抛出的是个好问题:一门团队仍然喜欢的语言,究竟为了什么才会被舍弃?不是被辜负的语言,也不是被硬塞过来的语言,而是自己亲手选定、还能在公开场合为之辩护的语言。这类问题的答案,通常比常见语言论战里的燃料更诚实。因为写作者并没有要借机发泄的宿怨。

正因如此,这篇文章才值得一读。因为 Scarf 并不是因为 Haskell 崩坏了才离开。恰恰相反,Haskell 兑现了自己大部分的承诺。而当人们问"为什么要离开 Haskell"时最常冒出来的理由 — 招人难、找不到人 — 在这篇文章里根本没有出现。Avi 给出的理由要具体得多,也更有 2026 年的时代感,值得细细咀嚼。

没有崩塌的承诺 — Haskell 守住的那些

先把天平摆正再往下说。Avi 明确写道,Scarf 把 Haskell 放上了严肃的生产检验台,而它的许多承诺确实兑现了。代码很稳定,类型系统抓住了真正的 bug,语言还逼着你去审慎地为领域建模。他们运行着背负合同 SLA 的服务,多年来一直没出问题,高性能代码也大体上写得不算费劲。

技术栈也很具体。API 是把 ServantBeam 叠在 PostgreSQL 之上构建的,而流量很大的 Scarf Gateway 则直接基于 WAI 实现为一个以性能为中心的服务。这些东西实实在在扛住了开源包的真实流量。

最诚实的一段是这样的。他承认,迁到 Python 后放弃的类型安全,到目前为止还没有让他具体地感到过遗憾。一个类型系统的狂热爱好者亲口这么说,分量是不一样的。当然,这是把双刃剑 — 类型悄悄挡下的事故,本来就是看不见的。但至少他没有夸大自己失去的东西。

这里还有一层私人色彩。Avi 说,学习 Haskell 让他成为了一名远比从前更好的程序员,那份亏欠感在文章里能感受到。惋惜的源头正在于此 — 这不是一篇复仇的文章,而是一篇重新协商一段旧关系的文章。在把这篇文章当作攻击某门语言的弹药去引用之前,这一点值得记住。

真正的原因 — 编译时间与智能体经济学

那么问题到底出在哪。Avi 点出的最大两点,是编译时间和生态系统的摩擦。其中编译时间尤为核心,而故事也正是从这里开始明显地"2026"了起来。

热起来的时候,一次迭代循环大约 20 秒,那种时候感觉很不错。问题出在冷启动。想象一下这样一种开发方式:把多个 AI 编码智能体分派出去,各自并行负责一条不同的分支 — 比如五个智能体同时探索五条分支。每条分支都需要一个干净的、用完即弃的构建环境。可如果智能体几分钟就写出了一个看起来像模像样的改动,然后要等上 15 分钟等冷构建跑完,那么编译器就不再是 一点小小的不便,而成了这条工作流里 最大的成本

用缓存来应对不就行了?Avi 的回答很冷静。缓存永远都不可能做到完美,而为了把缓存做得足够好所要投入的工程努力本身,就是问题的一部分。实际上,他们在打磨构建、缓存、Nix、开发环境和 CI 上花了大量时间。

核心的洞察在于经济账被重新改写了。智能体生成代码很便宜,卡住的时候却很贵。Haskell 是一门为"在编译时抓住错误"而优化的语言 — 在人是瓶颈的年代,这是一大美德。但在 LLM 能一瞬间吐出可运行代码的时代,这份美德的相对价值就下降了。 并不是语言变坏了,而是什么东西才昂贵这件事变了。

换个说法是这样的。几十年来的通行观念,是把错误检测尽可能往前挪 — 也就是左移(shift left),要在编译时失败,而不是在凌晨三点失败。这套逻辑立足于一个假设:写代码的人是稀缺资源。一旦把稀缺资源换成一个几秒钟就能吐出候选方案、永不知疲倦的生成器,瓶颈就转移到了反馈循环的延迟上。快但不那么聪明的循环,开始能够赢过慢但聪明的循环。这是个让人不太舒服的想法,但 Avi 没有回避它。

Avi 也简短地流露出对社区方向的一丝遗憾。他感觉,比起构建时间、上手引导、文档、示例和工具链,类型系统的研究被摆在了更优先的位置;而在 AI 这件事上,讨论更多地倒向了限制(restriction),而不是赋能(enablement)。

这里的"生态系统摩擦"到底指什么,值得说清楚。Avi 并不是在抱怨库不成熟,或者什么东西跑不起来 — 上面那套技术栈好几年都运转良好。摩擦在于围绕代码的那套机器装置。快速的智能体工作流所不断依赖的构建、缓存、环境、CI,以及一个注意力朝着别处的社区。这是一种和常见抱怨不同、因而更有意思的抱怨。

离开的方式,以及留下的教训

迁移的做法很教科书。所有新的 API 工作全部用 Python 起步,把 Python API 服务器和既有的 Haskell 服务器并排立起来,再把请求路由到合适的一侧,从动到的功能开始,一个一个地迁到 Python。这正是绞杀榕(strangler fig)模式。把既有代码移植到新语言这件事,因为把机械的活儿交给了 LLM,据说相当轻松。而且直到现在,Haskell 仍然在生产环境里运行,他们也依然尊重 Haskell。

有一个安静的反讽值得点出来。正是那份推高了"留下"成本的能力 — LLM 快到足以让编译器变成瓶颈的代码生成能力 — 把"离开"的成本压了下来。移植到另一门语言,历史上一向是件残酷的苦差事,如今由模型一行一行地搬运,大部分都变成了机械劳动。改变了"创造"经济学的工具,连"迁移"的经济学也一并改变了。

成果也写得很诚实。测试覆盖率比以往任何时候都好,热修复如今据说发一条 Slack 消息就能上线。但 Avi 没有夸大胜利 — 他很难说 PR 的吞吐量明显增加了,提交数噪声太多,而代码行数则被他自己一口咬定是个糟糕的指标。

从这里得到的教训不是"Haskell 不行"。而是:语言的适合度不是一个绝对值,而是相对于我们如何构建软件的相对值。七年前选择 Haskell 并没有错,是棋盘在它脚下发生了变化。而这整个决定都立在一个前提之上 — 以智能体为中心的开发,就是这个团队今后构建软件的方式。如果这个前提成立,那么正如 Avi 所说,这次迁移就是清晰而合乎逻辑的下一步。前提一旦动摇,这笔账也会随之改变。

也把风险明确点出名字。拿一份已被验证的优势去换一场押注,那终究还是一场押注。如果以智能体为中心的开发陷入停滞,或者那些原本由类型挡下的、看不见的 bug 随着规模增长开始浮现,一年后的账本看上去可能会大不一样。Avi 对那些无法测量的收益所保持的诚实是把双刃剑 — 因为成本同样可能在真正到来之前一直看不见。

所以,这是一个 n=1 的故事,是一家公司的经济账。它不是"大家都去用 Python 重写吧"这样的药方,而更像是一份邀请:请诚实地重新丈量,你自己的瓶颈究竟挪到了哪里。

结语

这篇文章最值得学的不是结论,而是态度。Avi 清清楚楚地承认了 Haskell 做得好的地方,不夸大自己得到的东西,也不掩饰自己的决定是立在特定前提之上的。一篇离开某门语言的文章,能保持这样的平衡并不容易。无论技术栈是什么,那份诚实 — 把什么被守住了、什么变了、什么还不确定区分开来的那种自律 — 才是真正值得照抄的部分。

若要读出更宏大的信号,那就是:随着 AI 改变代码被写出来的方式,我们给语言排座次的那根轴,正在悄悄地转动 — 从"语言能挡下多少",转向"语言能让你多快地重新尝试"。这究竟是进步还是陷阱,目前还不清楚。只是,那些早早察觉到这次转动、并对自己的数字保持诚实的团队,会比那些还在优化旧瓶颈的团队做出更好的决定。

参考资料