← 返回日报
略读 预计 2 分钟

Static types and shovels

摘要

文章分析了静态类型在 2000 年代失宠及近年复兴的原因。作者将早期 Java / C++ 比作 “纸糊的铲子”,因缺乏空安全、和类型(Sum Types)且语法冗长而效率低下;而现代语言(如 TypeScript、Rust、Swift)通过类型推导、空值处理和 IDE 集成,实现了 “好动态优于坏静态,但现代静态更佳” 的转变。

荐读理由

读者面向中文小圈子独立开发者扫技术创业信息,时间有限追求高信噪比。这篇文章以‘纸铲’类比,指出90年代初静态类型系统(如早期Java、C++98)根本帮不上忙——全靠人工处理null、产品类型、显式声明,写BufferedReader代码是灾难。而2010s后现代系统(Haskell Maybe、TypeScript T|null、Rust Optional)已能让编译器自动区null、实现‘使无效状态不可表示’,几乎零运行时空指针。额外加分是IDE补全遍地开花,类型信息让生产力直接拉高。读完这个类比与演进,就知道‘过去静态类型坏,现在好多了’这个深度洞见,能帮判断‘我项目该用哪种静态类型’的决策,避免掉队。

原文

Static types and shovels

I have a simple theory about why static typing became much less popular in the 2000s to early 2010s and started to get more popular again around the mid to late 2010s. It isn't because programming is a fashion led industry, but because the quality of the static type systems that were widely available improved.

Here's an analogy: say you want to dig a hole, would you rather use a shovel or your hands? If the shovel is any good then obviously you'd use the shovel. But what if the only shovel available to you was made of paper? You'd just be flailing uselessly at the ground with it. You'd be better off digging barehanded.

With a dynamic type system, you have to do all of the thinking about the states and contents of the variables and fields in your program yourself, with your own brain. The computer doesn't help you at all, nor does it hinder you. It's analogous to digging with your hands.

On the other hand, if you're given a poor static type system like the ones that were popular in the 90s and early 00s, such as the ones in early Java or C++98, it's analogous to a paper shovel. These static type systems fail to even help you with simple things like distinguishing nullable from non-nullable pointers. They don't have sum types, only product types. Meanwhile they require you to spend a lot of effort manually writing out type names all over the place. BufferedReader bufferedReader = new BufferedReader(new FileReader(filename)); is a small disaster.

If you contrast this to a modern type system like the one in say TypeScript, Haskell, MyPy, Swift or Rust, you'll always get:

  • Some way of distinguishing nullable from non-nullable types. Haskell has Maybe t. TypeScript has T | null. Swift has T?. Rust has Optional<T>. The type system can easily tell you where all the null checks need to be and if you missed one. In practice you almost never see null pointer errors at runtime.

  • At least one of sum types or union types, which let you follow the "Make invalid states unrepresentable" practice. This means you can have objects representing state machines, they have multiple fields, and each field exists when and only when the system is in a relevant state.

  • Some kind of type inference. We don't need to write let x: number = 5; when the compiler can just work out that let x = 5; is definitely a number.

Another thing which made static type systems more useful is that IDE features like method name completion have become more widespread. In the 90s Intellisense was a killer feature in Visual Studio, whereas in the 2020s similar features are available in just about every IDE and editor. So information you put into a static type system yields extra productivity benefits, entirely aside from its usefulness for checking programs for errors.

In conclusion:

  • A good dynamic type system is better than a bad static type system.

  • But now we have much better static type systems than we used to.

© Copyright 2026 Richard Barrell

Lobsters · 12 赞 · 6 评 讨论 → 阅读原文 →

这条对你有帮助吗?