The D Programming Language
D implements techniques that make contract programming easy, which makes for better quality assurance in programs. Making contracts part of the language itself makes it much more likely that they actually will be used, because the programmer doesn't have to implement them or use an outside library for them.
The simplest type of contract is the assert statement. It checks whether the value that is passed to it is true, and if not, it throws an exception. Assert statements can be passed optional message arguments to be more informative. Functions have two types of contracts, pre and post, signified by the in and out blocks preceding a function. The in contract must be fulfilled before the rest of the function is executed; otherwise, an AssertError is thrown. The post contract is passed the return value of the function and checks to make sure the function did what it was supposed to do before the value is passed to the application. When a program is compiled with the release option turned on, all asserts and contracts are removed for speed purposes:
int sqrt(int i)
in {
assert(i > 0);
}
out(result) { // the return value is
// always assigned to result
assert((result * result) ==i);
}
body
{...}
Another type of contract is the unit test. Its purpose is to ensure that a particular function or set of functions is working according to specification with various possible arguments. Suppose we have the following rather useless addition function:
int add(int x, int y) { return x + y; }The unit test would be placed in the same module, and if the unittest option is enabled, it would be run as soon as the module is imported and any function from it is executed. In this case, it probably would look something like this:
unittest {
assert(add(1, 2) == 3);
assert(add( -1, -2) == -3);
}
Because D has no preprocessor, conditional compilation statements are part of the language itself. This removes the numerous headaches caused by the preprocessor along with the infinite ways in which it can be used, and it makes for a faster compile. The version statement is a lot like #ifdef in C. If a version identifier is defined, the code under it gets compiled in; otherwise, it doesn't:
version(Linux) import std.c.linux.linux; else version(Win32) import std.windows.windows;
The debug statement is a lot like the version statement, but it doesn't necessarily need an identifier. Debugging code can be placed in the global debug condition or in a specific identifier:
debug writefln("Debug: something is happening.");
debug (socket) writefln("Debug: something is
happening concerning sockets.");The static if statement allows for the compile-time checking of constants:
const int CONFIGSOMETHING = 1;
void doSomething()
{
static if(CONFIGSOMETHING == 1)
{ ... }
}
The scope statement is designed to make for a more natural organization of code by allowing a scope's cleanup, success and failure code to be logically grouped:
void doSomething()
{
scope(exit) writefln("We exited.");
scope(success) writefln("We exited normally.");
scope(failure) writefln("We exited due to an exception.");
..
}
Scope statements are executed in reverse order. Script syntax DMD, the reference D compiler, supports the -run option, which runs the program taken from standard input. This allows you to have self-compiling D scripts, as long as the appropriate line is at the top, like so:
#!/usr/bin/dmd -run
D allows the automatic inferring of the optimal type of a variable with the auto-declaration:
auto i = 1; // int auto s = "hi"; // char[4]
This allows the compiler to choose the optimal type when that functionality is needed.
Some of you might be familiar with the foreach construct; it essentially says, “do this to every element of this array” as opposed to “do this a set number of times, which happens to be the length of the array”. foreach loops simplify iteration through arrays immensely, because the programmer no longer even has to care about the counter variable. The compiler handles that along with making each element of the array available:
char[] str = "abcdefghijklmnop"; foreach(char c; str) writefln(c);
You also can obtain the index of the element by declaring it in the loop:
int [] y = [5, 4, 3, 2, 1];
foreach(int i, int x; y)
writefln("number %d is %d", i, x);Finally, you can avoid worrying about the types of the variables, and instead use type inference:
foreach(i, c; str)
This opens up the field for numerous compiler optimizations that could be performed—all because the compiler is taking care of as much as possible while still providing the programmer with the flexibility to accomplish any given task.
Today’s modular x86 servers are compute-centric, designed as a least common denominator to support a wide range of IT workloads. Those generic, virtualized IT workloads have much different resource optimization requirements than hyperscale and cloud applications. They have resulted in a “one size fits all” enterprise IT architecture that is not optimized for a specific set of IT workloads, and especially not emerging hyperscale workloads, such as web applications, big data, and object storage. In this report, you will learn how shifting the focus from traditional compute-centric IT architectures to an innovative disaggregated fabric-based architecture can optimize and scale your data center.
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
| 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 |
| Trying to Tame the Tablet | May 08, 2013 |
| Dart: a New Web Programming Experience | May 07, 2013 |
- RSS Feeds
- New Products
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- A Topic for Discussion - Open Source Feature-Richness?
- Drupal Is a Framework: Why Everyone Needs to Understand This
- Home, My Backup Data Center
- New Products
- Paranoid Penguin - Building a Secure Squid Web Proxy, Part IV
- Developer Poll
- Trying to Tame the Tablet
- Looking Good
36 min 11 sec ago - Hey God - You may not be
4 hours 49 min ago - Reply to comment | Linux Journal
7 hours 22 min ago - Drupal is an Awesome CMS and a Crappy development framework
12 hours 1 min ago - IT industry leaders
14 hours 24 min ago - Reply to comment | Linux Journal
1 day 7 hours ago - Reply to comment | Linux Journal
1 day 9 hours ago - Reply to comment | Linux Journal
1 day 11 hours ago - great post
1 day 11 hours ago - Google Docs
1 day 11 hours ago
Enter to Win an Adafruit Prototyping Pi Plate 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 Prototyping Pi Plate 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
- Next winner announced on 5-21-13!
Free Webinar: Linux Backup and Recovery
Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.
In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.




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.