I've thought for a very long time about the class vs. struct choice in a container, and I came to a startling conclusion: it (almost) doesn't matter. Could be either, and the tradeoffs involved are nonessential. Here they are:

1. Using a class makes implementing members easier because there's no need to do work through an additional member. With a struct, you need a pimpl approach. For example:

struct Array {
    struct Impl {
        ...
    }
    Impl * impl;
    ...
    @property length() const { return impl->length; }
    ...
}

2. struct gives you more power in managing collection's own memory, as long as the collection doesn't escape item addresses or other addresses of internal handles. So all other things being equal, struct has a net advantage.

3. The creation syntaxes are different. For Phobos, I suggest adding a simple function make() to std.algorithm. make!T(a, b, c) returns a newly constructed object T by invoking the constructor with arguments a, b, and c. That way we can make client code virtually agnostic of the class/struct choice for a container.

That's it. Otherwise, one could use either to build a container. Let me note that I have reached the conclusion that containers should be at best reference types, with a meta-constructor Value!(C) that takes a container C and makes it into a value type.

This result is the end of a long journey. I am quite sure I have it right. If anything, I am amazed at how much dogma I had to unlearn before reaching it. And I'm glad I did - this is very D-like: I wasn't looking for a class-based solution, and I wasn't looking for a struct-based solution. I was only looking for the truth - and surprise, this slightly asymmetric duality came forth.

It seems Steve took the weekend off. At this point I'm poised to prepare a list of items that would condition putting dcollections in phobos. But I'd rather have Steve (and everyone) acquire their own motivation from my arguments, instead of operating changes as a concession.


Andrei

Reply via email to