Software development topics I've changed my mind on

Checked exceptions & error handling

  • Large subthread on Java checked exceptions: many like the idea (errors as part of the type), but think Java’s implementation is flawed.
  • Problems cited: “throws” clauses propagating up long call chains; generic exceptions like IOException being too vague; Java generics too weak to express things like E1 | E2.
  • Critics note checked exceptions don’t compose with higher‑order functions and lambdas, and push people to throws Exception or wrapping in RuntimeException, which defeats the purpose.
  • Comparisons drawn to Rust’s Result+?, Haskell/Rust Either/Result, effect systems, and Erlang’s “let it crash” philosophy. Some argue explicit error types everywhere become unwieldy too.
  • Unchecked exceptions are likened to “panic”; several say Java’s NPEs and arithmetic errors should have been treated as unrecoverable.
  • Overall: error modeling is widely seen as important; no consensus on the “right” mechanism.

ORMs, SQL, and data layers

  • Strong anti‑ORM sentiment: ORMs leak abstractions, hide queries, encourage N+1 problems, and make schema evolution and performance tuning harder.
  • Counterpoint: good data‑mapper ORMs (SQLAlchemy, Hibernate used carefully, Ecto) can provide identity maps, caching, relationship tracking, and convenient change tracking while still allowing raw SQL when needed.
  • Some note that teams avoiding ORMs often end up re‑implementing ORM‑like layers ad hoc.
  • DynamoDB: viewed as powerful but very specialized; praised when workload matches, condemned as “worst possible choice” for general apps. RDBMSs seen as hard to beat for most business systems.

Types, nullability, and language choice

  • Many agree typed languages help mixed‑experience teams and large codebases by constraining “footguns” and documenting contracts.
  • Nullability in Java/C# is a recurring pain point; annotations (JSpecify), Kotlin, and C#’s nullable references are mentioned as partial fixes.
  • Some enthusiasm for gradual and dependently typed languages, but others doubt they’ll enter the mainstream beyond light forms (TypeScript-style narrowing, Python type hints).

Code style, linting, and “craft”

  • The author’s line about people who stress over style being “insane weirdos” triggers a huge meta‑discussion.
  • Broad agreement on:
    • Use auto‑formatters/linters (gofmt, rustfmt, black, ruff, clang‑format) and let machines enforce consistency.
    • Arguing endlessly about brace position, 80 vs 120 columns, tabs vs spaces is wasted effort.
  • Disagreement on whether caring a lot about these details is “craftsmanship” or bikeshedding. Many distinguish:
    • Design/architecture, naming, and structure (seen as true craft)
    • Pure formatting minutiae (seen as low‑value once automated)

Upfront design vs iterative coding

  • Author claims “most programming should be done before code is written”; many push back.
  • Common view: you can’t foresee everything; prototypes and “discovery coding” surface constraints and better designs; plans must be revised after touching real code.
  • Emerging compromise: do enough upfront thinking (especially around data and boundaries), but expect to throw away a first implementation; design and implementation co‑evolve.

Functional vs OO and community dynamics

  • Several agree with “objects are good at what they’re good at; blind FP devotion is dumb.”
  • Many advocate multi‑paradigm use: immutable data + pure functions where possible; objects mainly as data carriers or boundary constructs.
  • Subthread about “the trouble with FP is functional programmers”: some complain about arrogance and silver‑bullet evangelism; others report only positive experiences. Consensus: zealotry (in any paradigm) is the problem.

Frontend development and tooling

  • The “Kafkaesque frontend” line resonates with many who dislike JS ecosystem churn, config complexity, and state‑management debates.
  • Others report happy experiences with TypeScript, React hooks, Vue, ClojureScript REPLs, or tools like Vite, arguing modern stacks can be pleasant and maintainable.
  • Hooks vs classes in React: some never adapted to hooks and found control flow/state harder to reason about; others defend hooks as more composable once patterns are learned.

Architecture: monoliths, microservices, serverless, databases

  • Many agree monoliths are underrated and microservices often overused; splitting should be justified by clear boundaries and scaling/org needs.
  • Serverless functions: divided opinions. Some with long Lambda experience are very happy; others find serverless backends complex to reason about, debug, and run locally, and fear long‑term lock‑in.
  • Strong preference overall for RDBMS for typical business apps; NoSQL and DynamoDB seen as niche fits needing strong justification.

Management, PMs, and soft skills

  • Good management widely viewed as rare but extremely valuable: shielding teams, clarifying goals, integrating feedback, and enabling growth.
  • Opinions on project managers are harsher: many say most add little value or create ceremony; a minority report excellent PMs who dramatically improve execution.
  • Soft skills (communication, empathy, requirements discovery) are seen as critical and under‑taught; suggestions include actively seeking feedback, facilitating meetings, and learning to translate between business and technical views.

Tests, coverage, and REPLs

  • Mixed feelings on code coverage: raw percentages alone are considered a poor quality metric and sometimes incentivize superficial tests; however, coverage as a heatmap of untested logic is valued.
  • Some advocate heavy comments in test code to explain intent; others warn about misleading/low‑quality comments.
  • REPLs and notebooks: some agree they’re better for exploration than design; Lisps/Clojure and JS/SQL workflows are cited where REPL‑driven development is central to design.