As you already say, if you are very concerned about performance in a situation with lots of small objects you can use structs. Simply ignoring structs because you are too lazy to use them does not make D slow. With a bit of experience and a few rules of thumb it's not hard to choose.
But structs do not have the same treatment as classes.
Your point is... what, exactly? They're for completely different purposes; of course they're treated differently. Otherwise, we'd only have classes or structs, not both.
I think maybe you're talking about what is called "scope" now. It allocates the memory for the class on the stack. Yeh, it doesn't cover every possible use case of by-value classes, but it can be a nice optimization.
And a heck of lot difficult to spot. At least, in C++, it's obvious what is a pointer and what it is not.
This is a valid concern, but I can't see what this has to do with the particular quoted part of the gp's post. He's pointing out that scope is useful, and you're complaining about not being able to tell if an arbitrary identifier has value or reference semantics. Huh?
That said, just because something doesn't have a star out the front in C++ doesn't mean it's a value type; I've seen some truly terrifying abuses of operator overloading. At least in D, it's trivial to find out: stick in a pragma(msg, whatIs!(x)) and bob's your uncle (note: whatIs is not in the standard library, but I've written similar templates before without much trouble.)
Yes you use structs when you want an efficient aggregate value type. Classes and structs have different semantics in D. It's pretty easy to choose once you get the hang of it. If you are likely to want to put virtual functions on the thing, make it a class. If you want to pass lots of them around by value, make it a struct. If you can count on your fingers how many instances you will have, make it a class -- the hit from allocation won't matter. There is some gray area in-between, granted, but in practice it's usually pretty clear, and the benefit is that you do completely eliminate the slicing problem by going this route. If you really can't decide you can also write the guts as a mixin and them mix them into both a class and a struct wrapper. Or just write it primarily as a struct, and aggregate that struct inside a class. The use cases that are left after all that are pretty insignificant.
Why do all that? no thanks. C++ is much better in this regard.
Yeah, why bother designing your program before you write it? After all, maybe you want to make your 16-byte vectors into classes, or turn GUI widgets into value structs!
Honestly, I'm amazed every time I see this argument. Let's try it from the other direction: Java seems to do pretty well without "plain old data" structs; clearly, you don't need structs to write a program. If you really don't want to have to engage your brain, just pretend structs don't exist.
D's template system has gone far beyond C++'s.
Nope. It hasn't.
It's even far beyond what C++0x is going to be.
Nope, it isn't.
Alias template parameters
C++ has typedef.
Yeah, so this combined with the 'auto' comment before lead me to believe you don't actually know what you're talking about.
Tell me, how do you typedef a function in C++? Or a string value?
Mixins are bad from a design standpoint.
I personally think you're wrong, but that's an opinion and not a valid argument. :)
C++ can do it with templates.
template isLowerAlpha(char c)
{
static if( 97 <= c || c <= 122 )
const isLowerAlpha = true;
else
isLowerAlpha = false;
}
And I can get even more complex from there. Maybe you could match D in terms of ability (which I doubt,) but you can't argue that it's anywhere near as intuitive or simple.
a host of compile-time introspection facilities, the ability to run regular functions at compile-time
And introduce big complications in the code.
C++ is just one giant complication. Hell, programming is complicated. First of all, introspection is invaluable; it means you can write templated types and functions that actually know about their type parameters. CTFE (compile time function evaluation) is also brilliant because it means you can move computations into the compile step. Yes, it adds complexity to the code, but the difference is minimal. Especially when the alternative is to either write and manually choose between a shitload of marginally different templates in the first case, and just moving that complexity to runtime in the second.
Really? So Boost can do this, then?
template dump(Ts...)(Ts values)
{
foreach( i,value ; values )
writefln("values[%d] = %s", i, value);
}
Note that the above code expands at compile-time, and works for an arbitrary number of arguments.
D metaprogramming is to C++ metaprogramming as C++ OOP is to OOP in C. It takes a technique that the previous language begrudgingly permitted and turns it into one that is actually supported by the language.
Nope. The C++ and D template type system are exactly the same.
I wasn't aware there was a special type system for regular code and templates in C++. I know there isn't in D. But saying the type systems in D and C++ are the same is just wrong: transitive const, immutability, sharing (coming soon).
In fact, if you ask Walter, all the template tricks in D are done using the C++'s Turing complete template system.
So I assume you could, with Walter's permission, post both your question and his response somewhere? Unless, of course, you're psychic.
You strike me as one of the C++ programmers who irrationally hates D because it's trying to improve upon and replace your favourite language, but you haven't spent enough time using D to actually be able to make an informed choice. That, or your knowledge of it is so out of date that it's no longer applicable.
You're more than welcome to your choice, of course. Just don't go around spreading FUD about D, please.