Features of D That I Love
Core Language Features Highlighted
.initdefault 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/invariantblocks andscope(exit)for robust postconditions and cleanup; some note prior art in Eiffel and Ada/SPARK. - Error handling:
scopeto 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) andpurefunctions: 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 likeidup(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
@nogccode 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.