$ cat choices/typed-languages.md
the call
Given the choice, I reach for a typed language. Static types are a guardrail that runs for free on every change: a tireless reviewer that catches a class of bugs at compile time instead of in production. It's the same instinct that picks Crystal, Rust, and TypeScript: pay a little discipline up front, stop paying for it at 2am.
A type system is the cheapest verification you’ll ever buy. It reads the entire codebase on every keystroke and refuses the shapes that can’t be right: the undefined, the missed caller, the refactor that didn’t land everywhere. That’s a class of bugs that never reaches a human, let alone a user. In a world where generation is cheap and verification is the job, types are verification you get for free. The one reviewer that never tires, never assumes, and never waves it through.
Types aren’t free everywhere. For a genuinely throwaway script or an exploratory spike, the ceremony slows the loop that’s the whole point. Dynamic languages still win on raw idea-to-running speed early, which is exactly why Ruby on Rails earns its place before the workload and the domain harden. And types are not a correctness proof: they check shapes, not logic. A green compile and a wrong answer live together comfortably. Chasing ever-more-elaborate type gymnastics past the point of payoff is its own trap.
It shows up across the stack I reach for: Crystal for type-safety with Ruby’s feel, Rust when safety and speed both matter and there’s no GC to hide behind, TypeScript to tame the JavaScript world. Different languages, one instinct: let the compiler carry the load a human otherwise has to. It’s the same reasoning that makes me overinvest in tests and CI. The train only moves as fast as the tracks, and a type system is track you lay once and ride forever.— see: choices / autonomy-with-guardrails
Types are guardrails, and guardrails are what make speed safe. Same belief as autonomy with guardrails, same belief as overinvesting in the deploy path. The cost of a type is paid once, at authoring time, by the person with the most context. The cost of its absence is paid repeatedly, at the worst time, by whoever’s on call. Push the cost to where it’s cheapest.
the gaps — what it costs even when it’s right
Types check shapes, not truth. They reduce a class of bugs, not all of them. Green types are not a passing test and never were. Leaning on them as proof is how a confident wrong answer ships.
The early-stage velocity tax. Before the domain is stable, types can slow the very iteration that finds product-market fit. Knowing when to take dynamic-language speed instead is part of the judgment.
Type-system gymnastics. Past a point, modeling something the type system resists costs more than the bug it prevents. The goal is fewer 2am pages, not a cleverer types file.