My/Principle/Make Illegal States Unrepresentable
- use the type system to make invalid combinations of state literally impossible to construct
- if a bad state cannot be represented, no code path can accidentally produce it
discriminated union vs. flag fields
- instead of
{connected: bool; socket: socket option} where connected=true and socket=None is a contradictory state, use Connected(socket) | Disconnected - the invalid combination cannot exist at the type level
non-empty list
- instead of
T list with a runtime non-empty check, represent as {head: T; tail: T list} - callers never need to handle the empty case because it is not part of the type
validated types
- instead of
string for an email address with runtime validation scattered everywhere, use an opaque Email type whose only constructor validates the format