Elegant D

H. S. Teoh hsteoh at qfbox.info
Tue Nov 25 19:37:21 UTC 2025


On Mon, Nov 24, 2025 at 05:18:21PM -0800, Walter Bright via Digitalmars-d wrote:
> I've been thinking about writing an article about what makes D an
> elegant language to program in. D is indeed an elegant programming
> language.
> 
> I'm interested in anecdotes, experiences and examples of Elegant D to
> incorporate!

I don't know what your definition of "elegant" is, but here are some of
my favorite features of D:

1. Built-in AA's.  AA's get a lot of hate for some reason, but they're
perfect for shell script replacements when you just need a hashtable
quick'n'dirty and don't really need nor care about the fine details of
hashtables.  Plus, D's AA's have no silly arbitrary restrictions, like
keys must be strings, or values must be strings.  Recently I had to use
sets in Javascript, it was horrendous.  Keys must be strings, which
means incessant conversions back and forth from objects (with the
associated performance hit), and values break in weird ways unless you
serialize them to strings first. In D, you just stick a struct into an
AA key or value and it Just Works(tm) by default.  In C++ you have to
write 2 pages of code just to make structs work as hash keys, not to
mention write ridiculously-convoluted boilerplate every time you want to
use the resulting hash table as a type, ridiculous!

2. Built-in unittests.  This one feature alone has improved my code
quality by leaps and bounds.  No need to install yet another tool just
for unittesting, no need to switch to a different file to write
unittests (which generally means I'd be too lazy to do it), no need to
switch to a different language to write unittests in. D's unittest
guilt-trip me into actually writing tests for my code, with the result
that bugs are caught early, saving lots of debugging time later.  Better
yet, ddoc'd unittests means you don't have to repeat yourself: write a
unittest once, and it serves as documentation on how to use your code,
no need to go through another round to write code examples! And you're
guaranteed that your code examples will actually compile, since they're
unittests.

3. Sane template syntax:

	auto myRangeFunction(R)(R range) { ... }

None of that nested angle-bracket horror in C++ that makes the language
impossible to lex until you parsed it first.

4. UFCS chains FTW.

5. CTFE.  None of the silly arbitrary limitations of C++'s constexpr,
you just write code like code and it works at compile-time just as it
works at runtime.

6. std.conv.to: the one-stop shop for all of your type conversion needs.
I know std.conv gets a lot of hate for some of the ugly parts of the
implementation, but the concept is sound and the practical usage so
incredibly convenient I chafe inside every time I have to write code in
a different language that doesn't have this capability.

7. DbI: I was able to write a serialization system that *didn't* require
you to write serialization boilerplate in every object you wanted to be
serializable.  It even worked with arbitrary classes, using static
this() inside a template wrapper struct to automatically include in the
executable the ctor calls you need to reconstruct your class
objects, *only* for the classes that you actually serialize in your
code, no more, no less. Bypassing Object.factory completely (because
that's *not* elegant).  The basic idea is this:

	private Object delegate()[string] globalCtors;
	template serialize(T) if (is(T == class)) {
		void serialize(T classObj) {...}

		// N.B.: not addressable from outside, gets instantiated
		// exactly once per class type you pass to serialize()
		struct deserializeImpl {
			// static this() ensures we only have one
			// instance per class type T
			shared static this() {
				globalCtors[T.stringof] = () {
					// We use compile-time knowledge
					// of T to return an instance of
					// T at runtime.
					return new T;
				};
			}
		}
	}

So in the deserialization code, once you know the name of the class, you
just look up globalCtors[className] to get a delegate that will create
an instance of that class and deserialize the incoming data into it (not
shown in code above for simplicity -- but basically you use
__traits(parameters) to introspect the class ctor's parameters, and use
that to generate code that reads the respective arguments from the
serialized data -- man, I love D metaprogramming! -- and then make your
ctor call -- all without touching Object.factory() at all).

Thanks to D's metaprogramming capabilities, once the above is setup you
don't even need to think about serialization anymore.  You just pass the
class object to serialize(), and the template, using DbI and static
ctors, auto-generate all of the requisite machinery to make it all work.
Not shown above is the version of serialize() that works for PODs and
structs -- I have that as an overload, so once all of that is in place,
all I need to do is to pass any type that I like to serialize(), and DbI
takes care of everything else.  Zero boilerplate FTW!

8. Have you heard about std.parallelism.parallel?  Suppose you have a
busy loop:

	foreach (data; bigArrayOfData) {
		doHeavyWork(data);
	}

and doHeavyWork() basically operates independently on each piece of
data.  How do you parallelize it to take advantage of multiple CPU
cores?  In other languages that I know of, you'd have to do a major
restructuring of your code, worry about race conditions, deal with the
complexities of working with mutexes, semaphores, and what-not.  In D?
Check this out:

	foreach (data; bigArrayOfData.parallel) {
		doHeavyWork(data);
	}

What, really? That's it?  Yes, that's it!  And what's even better about
this: .parallel is NOT a built-in language construct!  D gives you the
power to implement awesome things like this as *user code*, not as
in-language or in-compiler hacks.  Now *that's* elegance.

//

There are many other little things about D that I love, and that make
writing D such an elegant experience, but the above are the main ones
that come to mind.  There are probably many others.


T

-- 
If it tastes good, it's probably bad for you.


More information about the Digitalmars-d mailing list