When the slashdot article
The D Language Progresses appeared last weekend, I didn't expect
anything useful from the article comments ("This language will change
the world!" "We don't need another language!" "Beowulf Cluster!"), but I
took the opportunity to check out the latest language spec.
I'd seen the language before, and I approve of the general goal: create a
statically-typed, compiled, garbage-collected, module-based language which
is as similar to C++ as possible while excising the nastier bits.
If it were complete and well-supported, that's the kind of language
that I'd seriously consider switching to. However, a look through the spec revealed a language feature that's all
too common, and which makes me cranky.
On the list of C++ "features to
drop", D mentions
Creating object instances on the stack. In D, all class objects are by
RRGH! This is true of too many otherwise promising languages. Several
native value types are supported (int, float,
string, etc), but
user-defined value types are prohibited. Instead, all user-defined types
are "by reference", which means every class instance is heap-allocated individually.
For most of the programs I write (graphics, physics, etc),
int, float, and string aren't the only value
types I'm interested in. What about 3-dimensional points? Matrices?
Colors? These value types all simplify programming enormously,
especially when combined with operator overloading
(which D does support, incidentally). I'm not suggesting that D should support these natively; these
are just the sorts of custom types I expect to be able to
create with the class mechanism.
And it's important for these types to be true value types, and not
"by reference". Why? Because I commonly pack thousands of
instances into arrays for transport and manipulation. If all class
instances are "by reference", then arrays of those instances are
actually arrays of pointers, not arrays of the objects themselves.
The objects themselves get heap-allocated willy-nilly, and memory
coherence goes all to hell.
(It doesn't have to be this way, I suppose. You could prohibit instances on the stack but support
tightly packed instances in arrays on the heap. But
I see no evidence that D does this.)
The D documentation justifies its decision thusly.
This eliminates the need for copy constructors, assignment operators,
complex destructor semantics, and interactions with exception handling
stack unwinding. Memory resources get freed by the garbage collector,
other resources are freed by try-finally blocks.
True enough, though I'd much rather have "complex destructor semantics" for some objects if it means I can pack thousands of them into an array.
'Course, I'm really just saying "D doesn't seem appropriate for math-intensive,
very data-heavy applications." And perhaps that's not profound, or even
interesting. After all, garbage-collection is similarly
ill-suited to manipulating enormous datasets since dead
values don't get deleted right away. But I like garbage collection in general. I guess I want a language where some values can be garbage collected,
with other deleted explicitly. Or where large
structures can be tracked differently by the garbage collector, so they get deleted right away.
So my complaint may be irrelevant to D. But it still makes me cranky, because the only language I've found that's good at data-heavy stuff and general-purpose app work is C++. And C++ is, well... C++.