Fear makes you a worse programmer (2014)
Fear emerges as both a productivity killer and a safety mechanism in software engineering: it can paralyze developers, encourage defensive behavior, and lead to over-gamified metrics like test coverage targets, yet a healthy level of caution helps prevent outages and serious user harm. Commenters describe how brittle systems can persist despite near-100% test coverage when tests are poorly designed or driven by management mandates, contrasting that with environments where meaningful integration tests, strong type systems, and clear ownership let engineers refactor and tackle hard projects confidently. Broader themes include how organizational incentives, vague or doomed projects, and siloed communication can “set people up to fail,” and how experience, better tooling, and direct contact with users can turn fear into informed, responsible risk-taking.
Org culture, fear, and incentives
- One org with “meritocracy” and harsh performance reviews created pervasive fear: people avoided risky projects, gamed status reports, and big initiatives quietly failed.
- Wrong metrics and compensation led to defensive behavior and “metrics gamification,” not better outcomes.
- Some describe abusive managers / environments where fear and information gatekeeping caused burnout and self‑blame.
Tests, coverage, and fear of refactoring
- Multiple commenters agree: good tests can make refactoring and big changes feel safe; bad tests make things brittle.
- High coverage (95–99%) is not sufficient and can coexist with fragile systems.
- Coverage mandates from management are widely criticized for incentivizing useless tests and “busy work.”
Integration vs unit tests; what to test
- Strong consensus that high‑value tests are at stable boundaries: public APIs, CLIs, RPCs, microservice contracts, DB behavior.
- Many criticize fine‑grained unit tests with heavy mocking as brittle, low‑value, and obstructive to refactoring.
- Several advocate:
- Real DBs / external services in tests (often via containers or test harnesses).
- Property‑based testing and fuzzing for robustness.
- Fewer but higher‑level tests that let internals change freely.
Fear, risk, and responsibility
- One side: fear of breaking prod, losing data, or harming users is healthy; it drives careful thinking, testing, and logging.
- Others stress distinction between “caution” and “paralyzing fear”; fear that blocks change causes code rot.
- Some argue engineers today lean too cavalierly on rollbacks, tests, and “move fast,” underestimating real user harm.
Being set up to fail and vague projects
- Several recount projects with unclear goals, inadequate support, or impossible tasks (legacy hell, unmaintainable code, huge ports).
- These experiences created dread, burnout, and a sense of failure, especially early in careers.
- Senior engineers sometimes enjoy rescuing such projects by reframing the problem and talking directly to stakeholders—when the environment allows it.
Languages, types, and reducing fear
- Strong typing and modern languages (Haskell, Rust, Kotlin, etc.) are praised for removing classes of bugs and making changes more fearless with fewer tests.
- Some suggest “confident programming”: fail fast and loudly (e.g., panics on impossible states) instead of elaborate, fearful error‑handling paths.