Features of D That I Love

Core Language Features Highlighted

  • .init default initializers vary by type (e.g., int = 0, float = NaN, enums can choose a sentinel), seen as powerful but mentally heavier than simple zero‑init.
  • Design by Contract: in/out/invariant blocks and scope(exit) for robust postconditions and cleanup; some note prior art in Eiffel and Ada/SPARK.
  • Error handling: scope to guarantee no pointer escape; scope(exit)‑style constructs praised as a unifying mechanism that could replace much exception machinery.
  • CTFE: functions run at compile time when used in constant contexts, without special keywords; regarded as one of D’s standout features.
  • UFCS (Uniform Function Call Syntax): f(a)a.f(), enabling pipeline‑style code and making free functions feel like methods; also used heavily with templates.
  • $ shorthand for array length and overloadability for multidimensional slicing: liked by some, distrusted by others because overloading can hide semantics.
  • Attributes (in, out, inout, ref, scope, return ref) and pure functions: give strong semantic guarantees but contribute to perceived complexity.
  • Strong C interop: ImportC, BetterC, and direct calling both ways noted as a major but under‑advertised asset.

Contracts / Invariants Debate

  • One side: invariants are “just runtime asserts”; similar effects can be built via helper objects, aspects, or scope_exit‑like patterns.
  • Other side: having invariants as first‑class, auto‑run before/after public methods adds semantic weight; enables tooling, model checking, and clearer intent.
  • Subtlety noted: invariants often don’t hold in the middle of methods, so public methods calling each other require care; D’s mechanism exposes this.

Ergonomics & Readability

  • Some love UFCS chains (stdin.byLine...uniq...map!...sort...copy) as data‑flow pipes; others find them visually noisy and hard to parse, preferring explicit function calls or Elixir‑style |>.
  • Template instantiation with ! (map!(a => a.idup)) and names like idup (immutable dup) are seen as either neat or opaque, depending on taste and familiarity.
  • Operator overloading (including $) prompts concern about “clever” misuse vs defenders noting similar risk with + and that abuse is rare in practice.

GC, Memory Model, and “Better C/C++” Ambition

  • One camp: D’s garbage collector is “viral” – large parts of the stdlib (e.g., exceptions, string ops) rely on it, making truly @nogc code painful and limiting D’s viability as a C/C++ replacement.
  • Counter‑camp: GC is optional in practice; you can avoid allocating with it, use malloc/RAII/buffer types, BetterC mode, and treat GC as one tool among many.
  • Several participants argue this GC tension, and the long‑standing difficulty of a smooth no‑GC story, is an existential issue that has never been fully confronted.

Ecosystem, Tooling, and Adoption

  • Reasons cited for modest adoption:
    • No big corporate sponsor or marketing push during critical years.
    • Early history of D1 vs D2 and multiple runtimes created confusion.
    • Lacking or flaky tooling: LSP, debugging, autocomplete, DUB behavior; compared unfavorably to Rust/Go/Zig tooling.
    • Library ecosystem: many bindings out of date; using D at scale often means becoming upstream for lots of libs instead of solving the domain problem.
  • Desired but missing pieces: a first‑class, batteries‑included web framework (Django/Rails‑style); a strong, official GUI stack; coherent WASM story beyond “C subset only.”

Language Design, Complexity, and Niche

  • Supporters describe D as pragmatic, readable, and highly productive, with “batteries‑included” stdlib, strong metaprogramming, and multi‑paradigm flexibility (procedural, OO, functional).
  • Critics see a “jack of all trades” without a tight design: many overlapping features (parameter qualifiers, conditional compilation), complex stdlib internals, and no clear niche where it decisively beats existing languages.
  • Some feel D over‑pivoted to attract C++ users (despite GC skepticism) instead of leaning into attracting Java/C#‑style communities.
  • Overall sentiment: technically impressive, with beloved features (contracts, CTFE, UFCS, C interop), but held back by ecosystem, tooling, and a diffuse positioning in the language landscape.