[八卦] The angry emo D rant

sleets 2010-07-15
Disclaimer: This is a personal opinion of a long-time D 1.0 user. Every time I get asked about my experiences with D, it deranges into this. I thought I’d write it down and not re-type each time someone tosses the question. It may not reflect the actual state of D and certainly not the state by which it’s being marketed. If you’re positively emotional about D, you probably don’t want to read this. You might read http://h3.gd/devlog/?p=16 for a lighter (and older) version instead.

I knew quite a bit of C++ when I started learning D. You can never really get to know the beast completely, but I’d been around 4 years into it, feeling rather comfortable about it. Not to the point of being able to read Boost code, but enough for my daily needs ;) I also took up some Python before starting on D and knew a bit of x86 Asm.

Yet even with these traits, learning D was a long process – there are (still) no tutorials and articles to teach you some of the finer points of the language, traps and costs hidden therein. Back at the time, D was still evolving (I jumped aboard at around D 0.68) so the process involved going through the specification a few times, experimenting, reporting bugs and following the newsgroups.

After 6 or so years of using it, I’ve grown rather proficient with D and I think it allows me to be more productive than C++ ever could. Still, there are some traps and issues which made that difficult to achieve. The D language was meant to be easy to implement and the DMD compiler was supposed to be clearly designed and implemented. But as D matured, the growth happened through accretion and some concepts were glued on without much care to how they might interact at finer levels in the language as a theoretical entity as well as in the implementation.

You get local type inference which gets utterly confused with ‘properties’. You get a GC which is non-generational, non-concurrent and global, along with C-style (non-discriminated) unions. You get .di file generation, which is supposed to automatically provide something resembling C headers, and the feature is outright ‘borken’. There are template mixins, which are supposed to work just like copy-paste, but are far from it (yea, you can use ’string mixins’ but they’re just a huge and buggy hack anyway). Another example – the compiler will usually spectacularly poo itself when presented with cyclic imports. Not to say these are broken per se, but it might just happen that something explodes in a weird way and you get a cryptic error you can’t really fix, which would not occur without cyclic dependencies between modules.

And even if the bug gets fixed, when working on a larger project, you get to experience how poorly implemented the compilation model is – you can pass multiple .d files to the compiler and it will emit some symbols just once – e.g. template instantiations and initializers. But it will output multiple object files, and it’s not specified in which files particular symbols will land. Good luck performing incremental builds with that! And this once again leads me to D’s biggest issue – the toolchain. I needed to create my own build tool which does its best to incrementally compile projects. Walter might claim that DMD is fast, but it’s not exactly blazing when you confront it with a few hundred thousand lines of code. With C/C++, you’d split your source into .c and .h files, which mean that a localized change of a .c file only requires the compilation of a single unit. Take an incremental linker as well, and C++ compiles faster than D. With D you often have the situation of having to recompile everything upon the slightest change. The DMD frontend also takes an interesing approach to memory management – it’s based around a GC which is… disabled due to some bugs.

Another toolchain-related issue: need to profile some code written in C/C++? Just fire up VTune, CodeAnalyst, (Very) Sleepy or the Visual Studio Team Edition profiler. D on Windows? Sadly, it uses an archaic debug info format which goes into PE – the CodeView. And that in turn meant that I needed to write my own profiler. The situation on Linux is probably better, since DMD on Linux can finally generate proper debug info, since about… two months ago And yea, there’s built-in code-instrumentation via -profile, but I’m after a statistical profiler, not one with reduces my soft real-time app to a turtle.

On Linux you’re also lucky enough to be able to use the GCC linker, however on Windows you get to work with OPTLINK. It’s fast! It’s tiny! It’s 20 years old and will crash in your face when you feed it too many symbols. Its crash-rate was reduced slightly when Walter disabled the emission of WKEXT symbols (weak extern in OMF-parlance) from DMD, but I still need to compile parts of my projects without debug info and contract checking. I also needed to add a custom compiler pragma which suppresses symbol generation from code used only at compile-time.

But yeah, it’s not all bad – you get to use some handy meta-programming features, such as ’static if’, tuples, ’static’ foreach (loops unrolled explicitly at compile-time), compile-time function execution, as well as useful runtime constructs. Fast delegates, foreach/opApply, guaranteed initialization, handy SSE-optimized array ops, RTTI which sucks less than C++’s. There’s a layer of pretty tasty sugar on top, such as local type inference, delegate literals / lambdas, class references, lack of ‘::’ and ‘->’, built-in arrays (if you don’t care about the speed of their allocation) and a few others. In the end, these make me pretty productive and comfortable, but learning how to use the language and its tools optimally has been a painful experience. It would certainly be easier if the creators weren’t so busy flaming the Tango library (or just posting FUD and not bothering to correct it) and ignoring the (sadly, very small) community.

Users normally aren’t better, though. They try the language and expect everything to be rock solid – this has been since the beginning of D. So they play with it, decide it’s not ready yet and leave for other pastures. There are a few of who have been hanging around for about as long as D exists. Some of us have tried contributing code to the standard library, which turned out impossible. Then Tango was born as an alternative standard lib. There were discussions of it becoming the standard as it de-facto is within the 1.0 community, but they were later forgotten by the upper management. And now the Tango project is the black sheep as its contributors have grown generally tired of interacting with ‘the creators of D.’

Ah yea, and now there’s the “D 2.0″ thing which is more confused than ever. Does it want to be a better C, a better Java, a more contrived Boost? I can’t tell any more.

Someone please fork D 1.0 to hell. I’m already using a modified compiler ( no built-in Thread-Local Storage in DMD1?! Despite it only requiring changes in about 3 lines of the source code? WTF. ).



Global site tag (gtag.js) - Google Analytics