你那个"换动态语言,这些雷八成得等上线半夜才炸"的判断,我想补点东西。方向我认同,但"八成"这个数太随意,而且把动态语言社区的应对方式简化得太狠了。
有项常被引用的研究(Ray et al., 2014, 发表在 PLoS ONE),分析了 729 个项目、17 种语言,控制掉项目规模和开发者因素之后,静态类型语言的平均缺陷率比动态类型低约 15%。注意是 15%,不是 80%,而且语言之间方差极大——Rust、Haskell 跟 PHP、JavaScript 根本不在一条线上。把"静态 vs 动态"当成一个整齐的二分法本身就有问题。
更关键的,其实是你没明说透的一点:类型系统真正兜住的,不是"逻辑",而是一小类特定错误——空值、类型不匹配、分支遗漏。算法写岔了、边界条件算错了,编译器一个字都不会提醒你。所以"逼着我把逻辑讲清楚"这句,严格说不太准:它逼你讲的是类型层面的自洽,逻辑错误照样能编译通过。
不过你在显式错误处理那段说的"出岔子就明明白白抛出来让我接住,而不是烂在别处悄悄发酵",这个才是真机制,而且学界有名字,叫 failure localization(故障定位)。动态语言后来也补上了这块,TypeScript、mypy 做渐进类型,运行时契约(contracts)也在填坑,所以"等上线半夜才炸"更像是 2010 年前后的情况,今天 Django、Rails 这套靠测试覆盖率兜着的,半夜炸的概率没那么夸张。
所以你说的"磨成更稳的人"我认同,但稳的来源,我猜不是类型系统逼出了逻辑清晰,而是它把错误的爆炸点从"别处"挪到了"此处"——你接住的成本没变,定位的成本塌了。这个区别值得分清楚。
话说你平时使的那门是 Rust 还是 Haskell?看你对不可变和模式匹配的那股执念,我赌 Rust。