Parse, Don't Validate (2019)
Overall reception & scope of the idea
- Many commenters call the article one of their favorites and “seminal,” returning to it regularly.
- Core takeaway: it is not “don’t validate,” but “validate once, at the boundary, and turn raw data into richer types so the rest of the code can assume invariants.”
- Some note the title causes confusion, leading people to argue against positions the article doesn’t actually take.
Error handling vs “sane defaults”
- Debate around patterns like
TryParsewith silent fallbacks to “sane defaults.” - Several argue this is dangerous: invalid input should fail loudly, not be silently replaced, or bugs become hard to trace.
- Others counter that strict failure is sometimes user-hostile (e.g., malformed footnote, hotel room selection); partial success with warnings can be preferable, but must not be silent.
- Crowdstrike’s outage is cited as an example of not planning for invalid configs at all.
Using types to make invalid states impossible
- Strong support for modeling states in the type system: e.g.,
UncheckedEmail→ValidEmail→VerifiedEmail, orUservsVerifiedUser. - This avoids boolean flags and re-checks, and lets the compiler enforce correct usage.
- Disagreement on how far to go: some prefer only “valid” types; others find intermediate-state types essential, especially for multi-step workflows.
- Non-empty lists and smart constructors are discussed as practical patterns.
Language-specific perspectives
- Pattern seen as working well in F#, C#, Rust, TypeScript (with type predicates, Zod, effect/schema), and in FP languages with algebraic data types.
- Go’s zero values and JSON handling make this style harder, forcing more validation between parse and use.
- Haskell/OCaml list types and non-empty variants are dissected; historical choices are called “warts” but entrenched.
- Clarifications around
Void/voidvs unit types to avoid confusion between “no value” and “never returns.”
Validation placement, duplication, and security
- Advocates stress that once parsed into safe types, repeated checks (“shotgun parsing”) are a code smell and violate DRY.
- Others argue re-checking can be justified as defense in depth but may reflect “anxiety-driven development.”
- One concern: exposed APIs still need protection against malicious payloads and resource exhaustion; reply is that buggy parsers are just bugs, and centralizing parsing tends to improve, not reduce, robustness.