In love with D
After years of faithful and intense C++ coding, I found another language so awesome that it took my heart in a few month : the D programming language !
I discovered this language on a forum few years ago, but didn't see it like something that worth spending time on it.
In this time I made a shy try with it: LcdaUpdater. I've written it on Linux and I was impressed that running it on Windows did not required any code change despite using many git commands and manipulating files.
In fact I did not realized that the language was targetting the same goals I was trying to achieve with C++ : less code writing, easy to maintain/dig into and good performance.
While C++ is like a stack of powerful features (not always well) mixed together, D provides all of them (as far as I know) fitted to be easy to learn and comprehensive to read and write.
I learnt most things about D during my school year project: an autonomous sail boat named Tempest.
Two languages would have made their job: JS and C++. As I am as noob at JS as my workmate in C++, learning together a new language seemed a fair trade as we both were very enthusiastic about D.
We learnt the language with the ddili site and book
Mixin !
The string (which must be available at compile time) given to the mixin is injected in the code to be compiled.
mixin("writeln(\"Hello World\");");
//Will be compiled like:
writeln("Hello World");
And THAT is purely awesome ! It took me some month to find how to use it well.
Using std.traits, you can inspect many things in your code at compile time and get them as strings. Those strings can be injected as code by mixins.
My first interesting use of it is on XWiimoteD (home made D bindings for XWiimote): The goal was to load all function symbols from a dynamic library in function objects available at compile time, with minimal code writing:
//The function objects looks like this:
@dyncall int function(xwii_iface** dev, const(char)* syspath) xwii_iface_new;
// dyncall is a user defined argument to know if the function must be loaded from the library
//Load everything
foreach(member ; __traits(allMembers, xwiimote)){
static if(isCallable!(mixin(member))){
foreach(attr ; __traits(getAttributes, mixin(member))){
static if(attr.stringof=="dyncall"){
//Loading symbol in function object
mixin(member) = cast (typeof(mixin(member))) (dlsym(lib, member.ptr));
break;
}
}
}
}
CTFE
" Compile Time Function Evaluation"
Aka "the reason why mixins are awesome"
The D compiler does much work during the compilation. One of his task is to execute D functions during the compilation of the program.
For example, if you have a huge list of words separated by commas (ex: dictionary) and you want to put it in your program, simply paste it surrounded with double quotes and call split(",") on it: You will have your array of words and there will be no runtime cost !
The most impressive example is the compile-time regex. It works exactly like other regex, instead it creates an optimized automaton tuned for that special regex, giving slightly better performances than the world's fastest regex engine !
Of course, the regex still needs to be known at compile time.
Quality
Unit tests and contract programming are essential for large programs.
Why did I never see before a language that integrates that in its core?
It is so much simpler than using a C++ library:
// some random code...
unittest{
//and now you test your code
assert((3&2) == 2, "the bit operation did not work");
}
The compiler have a simple flag to enable or not the unittests and contract programming is disabled in release mode.
Give a try!
If you are familiar with C++, learning D will be very easy, quick and pleasant !
If you are not, consider that is an easy way to learn meta programming, compile time evaluation & réfection, ...