Self-Documenting Code

Debate over “self-documenting code” in JavaScript highlights tensions between clever idioms, such as using `||` for control flow, and straightforward, explicit conditionals that most developers find easier to read. Commenters argue over how far to rely on names, types, and short-circuit evaluation versus traditional comments, with many agreeing that code should explain the “what” while selective comments and types clarify the “why” and edge cases. The thread also touches on error-handling style, regex readability, function granularity, and the limits of relying solely on code structure as long-term documentation in evolving teams.

Use of || / short-circuiting for control flow

  • Many dislike patterns like cond || throwError() in JS: seen as non-idiomatic, harder to read, and potentially dangerous due to truthiness (e.g., 0/""/false).
  • Some note this is common in shell/Ruby, but others respond that shell syntax is notoriously opaque and not a good readability model.
  • Short-circuiting is generally seen as fine for a few conventional patterns (defaults, “cheap || expensive”, guarded conditions in loops), but controversial when used to encode primary control flow and exceptions.
  • A minority say they’d get used to it if consistently applied, but most call it cleverness over clarity.

Self-documenting code vs comments

  • Broad agreement that “self-documenting” really means “code that reads clearly,” not literally zero comments.
  • Several argue all comments (including JSDoc) are a smell: they rot, are ignored by tools/people, and often cover for confusing code that should be refactored.
  • Others push back: comments are essential for explaining why code is the way it is, documenting edge cases, hacks, business decisions, and serving as a “parity bit” to detect when behavior has drifted.
  • Middle-ground view: comments should explain non-obvious logic and rationale; avoid narrating obvious code.

Types, TypeScript, and JSDoc

  • Some see TypeScript (or strong typing in general) as the best form of documentation: machine-checked, close to the code, and more readable than JSDoc.
  • Others criticize heavy JSDoc/“docstring for every function” styles as redundant boilerplate that no one maintains.
  • There is concern that calling JSDoc-based static checking “self-documenting” contradicts the “no comments” ethos.

Password validation example & regex readability

  • Many call uncommented regexes a “code smell” and advocate brief comments or mapping rule names to regexes.
  • Suggestions include:
    • Using named constants for rules.
    • Refactoring to return specific failing rule or user-friendly error messages.
    • Avoiding \W due to subtle character-class issues.
  • Some note the article “missed the opportunity” to better factor this example.

Function structure, abstraction, and early returns

  • Disagreement on “tiny functions” vs single larger function:
    • One camp prefers local booleans and fewer jumps, arguing too many helpers make control flow hard to follow.
    • Another camp values small, well-named functions for abstraction, testability, and top-down understanding.
  • Similar split on early returns vs if/else nesting:
    • Early-return proponents like linear “guard clauses” and a clear happy path.
    • Critics warn that many return points can obscure which conditions apply at a given line.

Error handling and control flow

  • Debate over using exceptions for expected conditions, like invalid user input:
    • Some insist returning result objects/union types is superior and more type-safe.
    • Others argue exceptions are fine for these errors and more ergonomic than error codes.
  • Fail-fast styles are defended in some domains, but others warn about timing attacks and misusing abstractions like throwError().

Broader reflections

  • Several point out there is no universally self-documenting code; readability depends on audience, shared norms, and context.
  • Multiple comments stress that naming and visual structure do matter, though some downplay their impact relative to domain complexity.
  • A recurring theme: favor clarity over cleverness; refactor when feasible, but accept that comments and non-ideal structures are sometimes the pragmatic choice.