Don't use booleans (2019)
A blog post arguing against boolean parameters in APIs has reignited debate over how to design clear, maintainable function interfaces. Many programmers agree that multiple `true`/`false` flags quickly become unreadable and error‑prone, favoring alternatives such as enums, option objects, named or keyword arguments, and richer type systems to make invalid states unrepresentable. Others caution against absolutist rules, noting that simple booleans are fine in many cases and that real improvement comes from better abstraction, API design, and language features rather than banning a basic type outright.
Overall reception of the article
- Many agree the title is clickbait but the central idea is sound: naive boolean use leads to confusing APIs and hard-to-extend code.
- Others see the advice as too absolutist; booleans are fine in many places, and “never use booleans” could push beginners into needless complexity.
When booleans cause trouble
- Multiple boolean parameters (especially flags) degrade readability:
foo(true, false, true)is hard to understand and easy to misorder. - As features accrete, one flag becomes two, then three, etc., creating tangled conditionals and “boolean blindness.”
- Interdependent flags (e.g., arg3 only valid if arg1 is true) are hard to model safely with plain booleans.
Enums and richer types
- Enums (or sum types / tagged unions) make invalid states unrepresentable and document meaning explicitly.
- They upgrade better when a “two-state” assumption grows to more cases (e.g., multiple error reasons, more invoice types).
- Some worry about overhead: extra types, imports, and verbosity; others argue this is minor compared to debugging confusing flags.
Named / keyword parameters and options objects
- Many see named parameters / keyword arguments as the main cure:
RaiseInvoice(taxInvoice: false, sendEmail: true). - In languages without them, common patterns include:
- Passing a single “options” struct/object.
- Using language features like Python’s keyword-only args or JS/TS “options objects.”
- Some note you can’t force callers to use names, so APIs can still be misused.
Language-specific patterns and nuances
- JS/TS: options objects and string-literal unions are popular; opinions split on TypeScript
enumvs union-of-strings. - Python:
Literal[...]andEnumplus type checkers; keyword-only params help. - C/C++/Go: options structs and designated initializers used to simulate named args.
- Rust/Haskell/ML: strong enum/sum-type culture; related debates about
Option<Enum>vsEnumwith aMissingvariant.
Broader design themes
- Core principle: model domain concepts explicitly instead of “just another bool.”
- Booleans remain appropriate for truly binary, obvious cases (e.g., “active/inactive”), but many argue even there, separate methods or small enums can be clearer.