D is a strongly typed, natively compiled language, and Tango is one of its major companion libraries. The major intellectual forebear of D is clearly C++ (the language’s designer, Walter Bright, developed the first native C++ compiler, Zortech C++). However, D sheds many often-irritating legacy C++ features. Gone are the preprocessor and the C data types that retain compatibility with programs written for the PDP-11 more than 30 years ago. D defines from scratch an intuitive set of basic data types derived for modern hardware architectures, and puts in order C’s postfix declarations and the passing of variables to functions by defining in, out, and reference argument types. D also balances nicely Java’s compulsory overhead of subtyping polymorphism against the unattractiveness of the C++ virtual method declarations by using the “struct” keyword for defining objects that cannot be subclassed and reserving the “class” keyword for building class hierarchies with dynamic dispatch tables. Furthermore, D adopts innovations from other languages, such as Java, C#, and Eiffel, by supporting modules, delegates, and invariants.
However, at times, one is left with the feeling of creeping featurism run wild. There is built-in support for associative arrays and unit tests, complex numbers, template metaprogramming, and the innovative concept of compile-time function evaluation. The selection of features to include in the language seems arbitrary to me. If one adds these features to a programming language, why stop there and not add support for Extensible Markup Language (XML) constants, SQL statements, internationalization, matrices, or branch prediction annotations? There is also an unclear boundary between abstract concepts and implementation-related properties, such as the distinction between (kernel-implemented) threads and (language-supported) fibers. In general, D seems to be a language that solves yesterday’s problems admirably well, but fails to address modern challenges, such as increased memory latencies, multiprocessor programming, and distributed programming on the systems programming side, or Web, end-user, and domain-specific programming on the application side.
This book is clearly not a beginner’s guide, but does a nice job of introducing the language and its library to programmers versed in C++, Java, and C#. Programmers who are not familiar with all of these languages may find some of the descriptions slightly cryptic, as they assume knowledge of how these features function in another language. The writing is generally clear, although a chapter on the dry subject of procedural lifetime, in which the notion of delegates crops up without any prior introduction, mysteriously appears in the middle of the book and certainly seems out of place. Furthermore, the explanation of how the novel, interesting, and apparently useful “scope” statement works could be improved: currently the reader is left mystified on whether the statement’s scope is static or dynamic. In addition, the examples used throughout the book, although adequate for the purpose they serve, could be enhanced by being more useful and imaginative. Finally, the book lacks an index, an inexcusable omission in the age of electronic typesetting.
There is still room for a language better than D and for a book on D better than this one. In the meantime, both the language and the book are remarkable offerings.