近日,知名开源软件分发平台 Scarf 的创始人兼 CEO Avi Press 在一篇博文中宣布,经过长达七年的生产环境验证,团队最终“不情愿地”决定将核心后端从 Haskell 迁移至其他编程语言。这一消息迅速在技术社区引发热议——作为函数式编程语言的代表,Haskell 一直以其极强的类型安全与抽象能力备受推崇,为何一个深耕七年的团队会选择放弃?

从 Haskell 起航:追求正确性与高性能

Scarf 成立于 2017 年,专注于为开源项目提供许可证合规、使用统计和分发加速服务。早期技术选型时,团队将目光投向了 Haskell。在 Avi Press 看来,Haskell 的类型系统能够有效消除运行时错误,纯函数式特性也便于并发与并行处理——这对于一个需要处理大量数据流和权限逻辑的平台而言极具吸引力。此外,Haskell 强大的惰性求值机制让代码表达力出众,团队一度认为这就是“写一次、安心跑十年”的理想方案。

“我们当时被 Haskell 的优雅深深吸引。”Press 在博文中回忆。事实上,Scarf 的核心基础设施——包括许可证解析引擎、API 网关和费用计算模块——全部基于 Haskell 构建,并在早期表现出色。

七年之痒:理想与现实的裂缝

然而,随着业务规模扩大和团队扩张,Haskell 的短板逐渐暴露。Press 列举了几个关键痛点:

人才招聘是首要瓶颈。 Haskell 开发者在全球范围内都属于稀缺资源。Scarf 虽然身处硅谷,但要找到既精通 Haskell 又具备后端工程经验的工程师仍然异常困难。更棘手的是,即便招到人,新人上手周期通常需要数月——Haskell 的 Monad、 Lens 等抽象概念对许多程序员来说并不直观。

工具链与生态的“孤岛效应”。 相比 Go、Rust 甚至 Java,Haskell 的第三方库数量和质量都明显不足。Press 提到,团队曾多次因缺乏成熟的 ORM、消息队列客户端和监控集成库而不得不“造轮子”。更糟糕的是,Haskell 构建工具 Stack 和 Cabal 之间的割裂、包版本兼容性问题,以及 GHC(Haskell 编译器)的更新节奏,都持续拖慢开发效率。

生产环境的“隐形开销”。 Haskell 的惰性求值虽然优雅,却在内存管理和性能调优上带来了意外复杂度。团队反复遭遇“空间泄漏”问题——由于求值顺序不可控,某些函数在峰值流量下会意外消耗大量内存,导致 OOM。虽然理论上可以通过严格求值注解解决,但实际定位和修复这类问题需要极深的语言功底。

理性妥协:迁移至 Go,而非完全抛弃函数式

经过多轮评估,Scarf 最终选择将核心后端逐步迁移至 Go。Press 解释,Go 在并发模型、工具链成熟度、部署便利性和人才可获得性上均优于 Haskell,且团队已有部分成员熟悉 Go。值得注意的是,Scarf 并未完全抛弃 Haskell——部分高安全性、低变动的许可证逻辑仍保留在 Haskell 中,通过 FFI 与 Go 服务交互。

“这是一个痛苦的决策,但也是必要的妥协。”Press 写道,“我们仍然热爱 Haskell 的哲学,但公司需要生存,需要更快速地迭代。”

反思:并非 Haskell 的失败,而是生态的缺口

这一迁移案例为技术社区提供了深刻启示。一方面,它印证了“最佳语言取决于上下文”的常见观点——Haskell 在学术研究和编译器验证等领域依然不可替代,但在商业创业公司中,人才可获取性、开发速度和运维成本可能是更压倒性的考量。另一方面,Scarf 的经历也暴露出 Haskell 生态尚未解决的一些系统性问题:工具链碎片化、标准库演进缓慢,以及缺乏主流云服务商的深度集成。

Press 在博文结尾呼吁:“如果 Haskell 社区能将文档友好化、简化包管理并降低入门门槛,我相信更多公司会愿意留在它的世界中。”

截至发稿,Scarf 的迁移工作已完成 70%,预计在今年年底前实现全量转切。七年 Haskell 之旅,最终以一句“不情愿”画上句号——但这或许是技术演进中最真实也最理性的注脚。