"Within C++, there is a much smaller and cleaner language struggling to get out." —Bjarne Stroustrup, The Design and Evolution of C++

The D programming language aims to be an evolution of C++. A C++ coder looking at D code will likely feel quite at home, though a few things will jump out at them as odd.

Fair warning: I may get somewhat technical during the course of this writeup. If your eyes start to glaze over, don't say I didn't warn you.

The home of D is on Digital Mars' website: http://www.digitalmars.com/d/. The Digital Mars D compiler (dmd), which is currently the most complete implementation of the language, may be found there. It is available for Windows and Linux. This version is written by Walter Bright, who designed the languge. (Walter Bright also designed Zortech C++, the first native C++ compiler.)

Another D compiler, the GNU D Compiler (gdc), which acts as a front-end to GCC, may be found at http://home.earthlink.net/~dvdfrdmn/d/. It is available for a variety of platforms that GCC supports, including Linux, Cygwin, MinGW, and Mac OS X.

Like C++, D is a multi-paradigm language. It offers procedural, functional, object-oriented, and generic programming features. Also like C++, it is statically typed, and compiles directly to machine code. Unlike C++, it is garbage collected.

Also unlike C++, D does not aim to be back-compatible with C. This mainly allows D to clean up the syntax a great deal (no more trailing semicolon on struct and class definitions, for instance). It is, however, link compatible with C. Using most C APIs from one's D code is usually just a matter of re-writing the C header file in D. This has already been done with the entire C standard library, the Windows API, and the Linux API, and these are all part of the std.c section of the D standard library. Several other popular C libraries (such as SDL and OpenGL) have D bindings available as well.

D's standard library (which is called Phobos) is little more than adequate. It duplicates some of the functionality of the C standard library and has some more modern functions. These include .zip archive support, computation of MD5 digests, and input and output streams (which seem to have more in common with Java streams than C++ streams). Again, the entire C standard library is still available to fill in missing functionality.

Most notably missing from the standard library is a standard template library. There is a D Template Library project out there, but it remains a work in progress. The lack of such a library is somewhat mitigated by the fact that dynamic arrays (like C++'s std::vector) and associative arrays (sort of like C++'s std::map, only implemented with a hash table rather than a red-black tree) are built-in language features. Strings are simply dynamic arrays of type char.

Though D most closely resembles C++, it also steals a number of features from other languages. The one it takes the most from is Java, though it takes a wee bit of inspiration from languages like Python and Ruby. Perhaps the largest difference between D and C++ is the removal of multiple inheritance in favor of mixins and Java-style interfaces.

Actually, I take that back. The biggest difference between D and C++ is that it is garbage collected. This solves a great many problems caused by manual memory deallocation (viz. memory leaks). It is suprisingly common among C and C++ users to look down upon garbage collection as either slow, or for lazy coders. In my personal case, I did so because Java's garbage collector is (or perhaps was as I haven't bothered with the language in some time) not very good. D's promises to be pretty good. (Not least because the delete operator will immediately call the object's destructor, removing a major gripe about Java's GC, viz. the lack of deterministic destruction. It also has the probable speed advantage of compiling to machine code.)

If a user wishes to manually allocate their memory anyway, the C standard library is still available, meaning malloc and free are still available for abuse. Additionally, a class may overload the new and delete operators to get around the garbage collector entirely.

D does two more things that Java does and C++ does not: First, all objects are instantiated by reference. Second, all classes ultimately derive from a class Object. (However, templates in D may still accept primitive types as arguments, so the language neatly ignores the wrapper class hell that Java can put people through. It also still supports operator overloading.)

Although references are now the "default" choice for everything except the primitive types, pointers are still available. The primary use for pointers is for ease of integration with C libraries, though they also allow low-level systems work. For typical, "day-to-day" use, references alone will usually serve. Several C++ oddities are reversed: this and new return references rather than pointers, and a null keyword is introduced to represent both the null pointer (assigning a pointer to 0 is now an error) and the null reference.

An overview of the other features of the language may be found at http://www.digitalmars.com/d/overview.html. The language spec (which is the closest thing the language has to documentation) may be found at http://www.digitalmars.com/d/lex.html. The spec is quite technical in nature, and is probably incomprehensible to anyone who doesn't already know C++ (or Java, though the language is closer to C++).


Template instantiation

C++:

std::vector<int> v;

D:

dtl.Vector!(int) v;

(or:)

int[] v;


"Hello world!" example

C++:

#include <iostream>

int main(int argc, char* argv[]) {
    std::cout << "Hello world!\n";
    return 0;
}

D:

import std.stdio;

int main(char[][] args) {
    writef("Hello world!\n");
    return 0;
}

(It is also worth noting that void main(), void main(char[][] args), and int main() are defined as equally valid forms of main() in the spec.)


Template class example

C++:

template<class T> class A {
    T m_t;
public:
    A(T t) : m_t(t) { }

    // Adds the argument to m_t, returns result.
    T add(T u) { return m_t + u; }
};

D:

class A(T) {
    T m_t;
public:
    this(T t) { m_t = t; }

    /**
     * Adds the argument to m_t, returns result.
     */
    T add(T u) { return m_t + u; }
}

(D supports normal C++-style // comments, C-style /* */ comments, Java-style /** */ doc-comments, and nestable /+ +/ comments.)