Developing a plan for D2.0: Getting everything on the table

Steven Schveighoffer schveiguy at yahoo.com
Mon Jul 27 08:55:01 PDT 2009


On Mon, 27 Jul 2009 08:59:40 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail at erdani.org> wrote:

> Benji Smith wrote:
>> For example, should the author of a container library prefer classes or  
>> structs?
>
> I've been struggling with this forever. I don't know. I don't even know  
> whether reference or value semantics are best for containers. I don't  
> know whether abstract container interfaces and container-independent  
> code are a net win; experience with STL seems to say "don't" and  
> experience with Java seems to say "ho-hum".

If you use classes with interfaces, then ranges can't be part of that  
equation.  Since ranges are for the most part structs, and structs can't  
currently support interfaces, you can't make an interface that accepts a  
range.  That's not to say ranges can't be part of classes, but they can't  
be part of interfaces.

When making dcollections, I tried to separate out what should be part of  
the interface, and what should be specific to each class.  What I found  
was that all the cursors (what you would call unsafe C++ iterators ;) )  
could not be interface types, because they were structs for performance.   
However, I wanted to have the ability to have two different containers  
ineroperate seamlessly with eachother, as long as the types were the  
same.  That suggested interfaces.  What I ended up with is two ways to  
deal with container elements, opApply and cursors.  I am biased of course,  
but I think it's the perfect combination of power, ease of use, and low  
cost of implementation.

I still have yet to incorporate a range concept into my design, but I  
think it can be bolted on using a container with two cursors.

>
>> Should other (non-container) modules accept container classes as  
>> arguments? Or only container interfaces (if there are any such things)  
>> or just ranges?
>
> I think ranges should be preferred wherever applicable.

Ranges imply templated functions, which mean:

- no polymorphism (although this requirement is questionable, most users  
don't derive from containers).
- no usage of interfaces
- each call may compile a new function (i.e. code bloat)

There is something to be said with the power of opApply here, since you  
can do it with a class or interface, with very decent performance (only  
one virtual call).

As I said earlier, a combination of both ranges and interfaces would be  
ideal.

-Steve



More information about the Digitalmars-d mailing list