Appendices: Projects, Interview Questions, Cheat Sheet & Resources

Capstone projects, interview and review questions, a D cheat sheet, D for C++ / Java / C# / Python / Rust developers, and resources.

Appendix A: Capstone Projects

Beginner: CLI Utilities. Reimplement wc, grep, and uniq with std.getopt, ranges, and file I/O. Add unittests.

Beginner: Contact Manager. Structs, associative arrays, JSON persistence (std.json), a menu-driven CLI.

Intermediate: Log Analyzer. Range pipelines over large files (byLine, splitter, group), std.parallelism for speed, CSV/JSON output, benchmarks.

Intermediate: Markdown → HTML Converter. A parser using ranges and std.regex, templates, documented unittests, Ddoc output.

Intermediate: REST API Service. vibe.d REST interface + SQLite/PostgreSQL, authentication, JSON (de)serialization, Docker deployment.

Advanced: Compile-Time Serialization Library. UDAs + __traits + static foreach to generate JSON/binary serializers for any struct. CTFE-validated schemas.

Advanced: Interpreter for a Small Language. Lexer, recursive-descent parser, SumType AST, tree-walking evaluator, REPL. Use Pegged for a PEG-based version.

Advanced: @nogc Data Structures. Allocator-aware Vector, HashMap, and RingBuffer using std.experimental.allocator and RAII. Test with -betterC.

Advanced: Concurrent Web Crawler. std.concurrency message passing or vibe.d fibers, rate limiting, robots.txt, results in a database.

Systems: C Library Binding. Wrap libcurl, SQLite, or zlib with ImportC/dpp. Provide an idiomatic @safe range-based API. Publish to code.dlang.org.

Systems: BetterC Firmware or WASM Module. A blinky/UART program for Cortex-M with LDC, or an image filter compiled to WebAssembly and called from JavaScript.

Graphics: 2D Game. raylib-d or bindbc-sdl, an entity system using structs and ranges, @nogc game loop.

Appendix B: Interview and Review Questions

What are D's main design goals and paradigms?

Name the three D compilers and when you'd use each.

What is UFCS? Give an example.

Difference between static arrays, dynamic arrays, and slices?

What does $ mean inside an index expression?

How do string, wstring, and dstring differ? What is autodecoding?

Explain ref, out, in, lazy, scope, and auto ref parameters.

What is final switch?

How do scope(exit), scope(success), and scope(failure) work?

What is the difference between enum, const, and immutable constants?

Structs vs classes in D: semantics, allocation, inheritance?

Why are class destructors non-deterministic? How do you get deterministic cleanup?

What does private mean in D (module-level)?

What are alias this and opDispatch used for?

How does operator overloading work (opBinary, opCmp, opApply)?

Explain const vs immutable vs inout. What does transitive mean?

What is shared, and why are globals thread-local by default?

Exceptions vs Errors? Why not catch Errors?

What are contracts (in, out, invariant)? How do they behave under inheritance?

What is std.sumtype, and how is match checked?

Explain the range concept and the range hierarchy. How do you write a custom range?

What is lazy evaluation in Phobos pipelines? When do you call .array?

How do templates, template constraints, and IFTI work?

What is CTFE? What are its restrictions? Give a use case.

Explain static if, static foreach, version, and debug.

String mixins vs template mixins?

How do __traits and std.traits enable compile-time reflection? What are UDAs?

How does the GC work in D? When does it run? How do you avoid it?

What do @safe, @trusted, and @system mean? What is DIP1000?

Explain pure, nothrow, @nogc, and attribute inference.

Copy constructors vs postblit? How does move work?

What is BetterC, and what features are unavailable?

How does std.concurrency message passing ensure safety?

How do you parallelize a loop with std.parallelism?

What are fibers, and how does vibe.d use them?

How do you call C functions from D? What is ImportC?

How does D interoperate with C++?

How do you profile GC allocations and CPU time in D?

Implement a generic Stack(T) with a template constraint and unittests.

Write a range that yields prime numbers lazily.

Use __traits to auto-generate a toString for any struct.

Write a word-frequency counter with a range pipeline.

Implement a @nogc ring buffer with RAII.

Build a producer/consumer with std.concurrency.

Write a CTFE function that generates a lookup table, and verify it with static assert.

Appendix C: D Cheat Sheet

import std.stdio, std.algorithm, std.range, std.array, std.conv, std.string;

// ===== Variables =====
int x = 1; auto y = 2.0; const z = 3; immutable w = 4; enum K = 5;
int[] arr = [1, 2, 3]; int[3] fixed; int[string] aa = ["a": 1];
string s = "text"; char[] mut = s.dup;

// ===== Control flow =====
if (x > 0) {} else {}
foreach (i; 0 .. 10) {}
foreach (i, v; arr) {}
foreach (ref v; arr) v++;
while (x < 10) x++;
switch (s) { case "a": break; default: }
final switch (color) { case Color.red: break; case Color.green: break; }

// ===== Functions =====
int add(int a, int b) { return a + b; }
auto twice(int v) => v * 2;
T maxOf(T)(T a, T b) if (is(typeof(a > b))) { return a > b ? a : b; }
void mod(ref int v) { v++; }
auto lam = (int a) => a * a;

// ===== Types =====
struct P { int x; this(int x) { this.x = x; } }
class A { void f() {} }  class B : A { override void f() {} }
interface I { void g(); }
enum Color { red, green }
alias IntList = int[];

// ===== Errors =====
try { throw new Exception("x"); } catch (Exception e) {} finally {}
scope(exit) writeln("done");
enforce(x > 0, "msg");
assert(x > 0);
static assert(int.sizeof == 4);

// ===== Ranges & algorithms =====
arr.map!(a => 
…
dmd -run app.d | rdmd app.d | ldc2 -O3 -release app.d | dmd -unittest -main -run m.d
dub init | dub run | dub test | dub build -b release | dub add pkg | dmd -betterC app.d

Appendix D: D for C++ / Java / C# / Python / Rust Developers

templates + constraints const fn / macros GC + RAII + manual immutable/const (transitive) exceptions (+ Nullable, sum types) Key gotchas:

C++ devs: there's no header/source split, private is module-level, classes are always references, struct default constructors are disallowed, and there's no multiple class inheritance.

Java/C# devs: structs are values (with stack allocation and RAII), there are templates instead of erased generics, free functions plus UFCS replace static utility classes, and globals are thread-local by default.

Python devs: D is statically typed and compiled, and it uses braces and semicolons. Ranges feel like generators/itertools.

Rust devs: the GC is available (opt out with @nogc), safety is opt-in with @safe + DIP1000, and there's no borrow checker by default (@live is experimental).

Appendix E: Resources

dlang.org: Language specification, Phobos and druntime docs, changelog, articles, the D Blog

tour.dlang.org: the interactive DLang Tour run.dlang.io: Online compiler (with DUB packages, assembly/IR output)

code.dlang.org: The DUB package registry forum.dlang.org, the D Discord, r/d_language, DConf talks on YouTube

*Programming in D*: Ali Çehreli (free online at ddili.org; excellent and comprehensive)

*The D Programming Language*: Andrei Alexandrescu (D2 classic) *D Cookbook*: Adam D. Ruppe *Learning D*: Michael Parker *D Web Development*: Kai Nacke (vibe.d)

*D Templates: A Tutorial*: Philippe Sigaud (free, on GitHub) Learning and Practice

Exercism D track, Rosetta Code D solutions, Advent of Code in D, the "This Week in D" archives, Adam Ruppe's "D Tips" blog, Steven Schveighoffer's and Mike Parker's articles on the D Blog Suggested 12-Week Study Plan Setup, syntax, types, operators, UFCS Control flow, functions, strings Arrays, AAs, structs, classes

Interfaces, enums/sum types, modules, qualifiers Errors, contracts, delegates, ranges

Phobos algorithms, operator overloading, testing/docs Templates, constraints, CTFE, static if/foreach Mixins, reflection, alias tricks

Memory, safety, attributes, move semantics, BetterC, low-level

Concurrency, parallelism, fibers, C/C++ interop Phobos tour, files/OS, web/vibe.d, DUB, domains 47–49 + Capstone

Debugging/profiling, best practices, internals Final tip: Read *Programming in D* alongside this course, use run.dlang.io to experiment, write unittest blocks for everything, and try a CTFE + mixin project: that's where D really shines. Happy coding! 🚀