GooberMan
Scripting Nut

Posts: 1146
Registered: 02-01 |
Alright, so it's a double reply. Sue me.
D is quite a nice language to use. Its aim is to be a successor to C++ for low level systems programming. I think it's almost at the point where you could use it as such. In terms of speed, it's almost as fast as C++. There are many language-supported features that are done more efficiently in D than any C++ system could manage, but one major thing that holds it back speed wise is that every method of your classes are virtual by default. But it's a tradeoff with benefits there - D's type system is far more robust and safer than C/C++'s.
Arrays aren't just a pointer. They're a tuple of a pointer and a size. Going outside of the bounds of your array becomes far more difficult as a result. As a result of this, it's also got a fairly elegant solution for strings - as the string keyword is synonymous with immutable char[]. Any array operation is subsequently a valid string operation, including the ~ concatenate operator and slicing arrays for tokenising. It's also a fair sight cleaner than C#'s string implementation, which is the only basic type that behaves as a reference type rather than a value type.
I'm finding a heap of usage out of Universal Function Call Syntax. Basically, a function prototype of R function(T val) can be called in a similar manner to a property, ie val.function. It's not immediately obvious, but it straight up means you can extend the inbuilt types. floatVal.squareRoot for example is entirely possible. I wrote a WAD loader in D as an exercise, and I've found stuff like rotation.DoomRotationToRadians to be pretty handy. Combined with templates, it's a really freaking powerful feature to have.
Speaking of. Templates are far less of a headache than C++. Specialisation is fully supported, so you can restrict your template to certain types or other qualifiers.
There's other cool things too, such as opDispatch. Have you ever wanted to swizzle a vector in C++ code? opDispatch lets you interpret any old accessor string on your classes/structs and decide what to do with it. vector.xzy is completely valid if you've created the correct opDispatch function.
By far the most valuable thing though in D is that the preprocessor has been eliminated. There's still conditional compilation via things like the version keyword (which handles processor architectures, unit testing, etc). static if is also quite valuable in that regard - it basically means that swizzle operator I mentioned above can be compiled away to nothing. But by far the best part with the most ramifications for your coding style is the fact that compile-time code execution is implemented. Any D code you write can be evaluated and run at compile time and thus affect the output of your code. It's meta programming on a whole new level. The kind of stuff you can do it with is nuts. We're using it extensively at the moment, I can't really go in to details yet. Needless to say, it makes #define look as archaic as it actually is, and other metaprogramming solutions weak in comparison. The amount of code it cleans up and effort it saves over the corresponding C++ equivalent is insane. And since you're evaluating stuff at compile time, massive C++ systems can effectively be compiled out to nothing in D.
As D fully supports the C ABI, it can also bind all the commonly used libraries (Phobos in fact has bindings to the C runtime functions). It also has limited compataibility with C++. There isn't a single consistent C++ ABI out there, so D has limited itself to supporting the C++ virtual function table. If you write matching interfaces in C++ and D, you can cross-communicate between the two with your objects.
I'm not an expert on D yet, but I'll be getting more knowledgable and confident in the language both out of necessity and by choice.
|