The D Programming Language
During the past few decades, programming languages have come a long way. In comparison to the dawn of UNIX and C, when compiled languages were just getting their start, today's world is full of languages with all sorts of goals and features. In this article, I discuss one such language, D from Digital Mars. D is a natively compiled, statically typed, multiparadigm C-like language. Its aim is to simplify development of any type of application—from kernels to games—by combining the performance and flexibility of C with the productivity-boosting factors of languages, such as Ruby and Python. It originally was conceived by Walter Bright, the man who wrote the first ANSI C++ compiler for DOS. The reference compiler is freely downloadable for both Windows and Linux, and the front end is licensed under a dual GPL and Artistic license.
GDC is a D compiler, which uses the GCC back end and is distributed under the GPL. D's features include the lack of a preprocessor, a garbage collector, flexible first-class arrays, contracts, inline assembler and more. With all this, it still maintains ABI compatibility with C, allowing you to use all your old C libraries from D easily, with little work. The D standard library includes bindings to all standard C functions as well.
In D, the Hello World program goes like this:
import std.stdio; // standard i/o module
int main(char[][] args)
{
writefln("Hello world!");
return 0;
}
writef is D's typesafe version of printf; writefln adds a newline character at the end. Garbage collector D includes an automatic garbage collector, relieving the programmer of the need to manage memory explicitly. This allows programmers to focus more on the task at hand, as opposed to having to worry about the condition of each memory chunk. Furthermore, it eliminates a whole class of bugs dealing with dangling pointers and invalid memory references. In times when the GC would slow the application down, there is always the option of turning it off altogether or using C's malloc and free for memory management.
In D, modules are imported using the import statement and have a one-to-one correspondence with source files, with the period as the path separator. Each symbol within a module has two names: the name of the symbol and the name of the symbol prefixed by the module name, which is called the fully qualified name or FQN. For example, writefln can be referred to as writefln or std.stdio.writefln. For cases when the FQN is preferred, the static import statement imports the module's symbols but avoids putting them into the global namespace. For example, both the std.string and std.regexp modules include functions for find, replace and split. Because I'm more likely to use pure string functions than regular expressions, I would statically import std.regexp, so that whenever I wanted to use any of its functions, I would have to be explicit, whereas I simply could call the string functions by their regular names.
Modules can have static constructors and destructors. The static this() function in any module is the static constructor and is invoked before main(); after main has returned the static, ~this() function is invoked. Because modules are imported symbolically, this means there are no header files. Everything is declared once and only once, eliminating the need for declaring functions in advance or declaring classes in two places and trying to keep both declarations consistent.
In D, there is a distinction made between an alias and a type. A typedef introduces an entirely new type to the type-checking system and to function overloading, which are discussed later. An alias is a simple replacement for a type, or optionally a symbol:
alias int size_t; typedef int myint; //can't implicitly convert to int alias someReallyLongFunctionName func;
In D, arrays are first-class types in every way. D contains three types of arrays: static, dynamic and associative arrays. Array declarations read right to left; char[][] is interpreted as an array of arrays of characters:
int[] intArray; // dynamic array of ints int[2][4] matrix; // a 2x4 matrix
All arrays have length, sort and reverse properties. Associative arrays are arrays where the index is something other than sequential integers, possibly text strings, structs or arbitrary integers:
import std.stdio;
int main(char[][] args)
{
int[char[]] petNumber;
petNumber["Dog"] = 212;
petNumber["cat"] = 23149;
int[] sortMe = [2, 9, 341, 23, 74, 112349];
int[] sorted = sortMe.sort;
int[] reversed = sorted.reverse;
return 0;
}Dynamic and static arrays can be sliced with the .. operator. The starting parameter is inclusive, but the ending parameter is not. Therefore, if you slice from zero to the length of an array, you get the whole array:
int[] numbers = [1, 2, 3, 4, 5, 6, 7]; numbers = numbers[0..2] // 1-3 now
Finally, D uses the ~ operator for concatenation, as addition and concatenation are at their most fundamental two different concepts:
char[] string1 = "Hello "; char[] string2 = "world!"; char[] string = string1 ~ string2; // Hello world!
This is a prime example of how D implements a lot of syntactic sugar on top of more low-level routines to make the programmer more focused on the implementation of the task itself. Strings D takes arrays one step further. Because strings are logically arrays of characters, D has no built-in string type; instead we simply declare an array of characters.
Furthermore, D has three types of strings: char, a UTF-8 codepoint; wchar, a UTF-16 codepoint; and dchar, a UTF-32 codepoint. These types, along with standard library routines for manipulating unicode characters, make D a language suited to internationalized programming. In comparison with C, D strings know their length, eliminating even more bugs and security issues dealing with finding the elusive null terminator.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
| Non-Linux FOSS: Seashore | May 10, 2013 |
- RSS Feeds
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Using Salt Stack and Vagrant for Drupal Development
- Dynamic DNS—an Object Lesson in Problem Solving
- New Products
- Validate an E-Mail Address with PHP, the Right Way
- Drupal Is a Framework: Why Everyone Needs to Understand This
- A Topic for Discussion - Open Source Feature-Richness?
- Download the Free Red Hat White Paper "Using an Open Source Framework to Catch the Bad Guy"
- Tech Tip: Really Simple HTTP Server with Python
- Roll your own dynamic dns
2 hours 21 min ago - Please correct the URL for Salt Stack's web site
5 hours 33 min ago - Android is Linux -- why no better inter-operation
7 hours 48 min ago - Connecting Android device to desktop Linux via USB
8 hours 17 min ago - Find new cell phone and tablet pc
9 hours 15 min ago - Epistle
10 hours 44 min ago - Automatically updating Guest Additions
11 hours 52 min ago - I like your topic on android
12 hours 39 min ago - This is the easiest tutorial
19 hours 14 min ago - Ahh, the Koolaid.
1 day 53 min ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




Comments
What a badly designed language
I can't see any better than C/C++ or Python.
the "~" concatenating operator is ugly than any other language,
the gc makes it not a pure compiling language.
It's pure compiling
It's pure compiling language! "~" is used becouse, "+" means addition, not concatenating. You can find rational arguments for this and other problems on D web page.
BTW. "inout" parameters are now renamed to "ref".
As of 1.011
"BTW. 'inout' parameters are now renamed to 'ref'."
As of 1.011
Funny though, its badly designed because it uses ~ and has gc. And I wonder what pure compiling means if gc makes this no longer true?
Why makes gc pure compiling no longer true
Why makes gc pure compiling (whatever that means) no longer true ? GC is done by the runtime and has nothing to do with compiling. D is a "pure compiling" language (as pure as you can get - there is nothing more pure than compiling into platform dependent native code). And why is a language badly designed just because it has the option to use garbage collection (in D you can manage memory by yourself and turn garbage collection completely off, if you want to) ?
Using ~ for concatenating arrays and not + makes sense because your not adding strings like you are adding numbers. But that might be just a matter of taste.
But if these two things are the only criterions for you to decide if a language is good or bad designed, you should better not become a language designer.
Improvements over C++
For a (not complete) list of things which are "improvements" over C++ just take a look at
http://eureka3d.com/blog/2006/the-d-progamming-language-a-pleasant-surpr...
As always this is a matter of taste and personal preference. But C++ had to be designed to be backward compatible to C, so some things could not be as clean designed as they should be and make the language more complicated and error prone.