improvement request - enabling by-value-containers

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Tue Dec 14 14:05:47 PST 2010


On 12/14/10 3:29 PM, Jonathan Schmidt-Dominé wrote:
> Hi!
>
> Just about my experiences: When trying to hack some algorithms quickly in
> Ruby I made a lot of mistakes because I had to care about a .clone
> everywhere and because Array.new(5, []) does not work as expected (sorry,
> but Array.new(5) { return [] } is not nice). So in fact C++ made my life
> easier than the new, stylish, simple Ruby-programming-language, because of
> the great by-value-containers in the STL.

Thanks for sharing.

> However, some reasons for by-value-containers:
> *First of all you often have to deal with mutli-dimensional data-
> structures,
> you map something to a map of lists of whatever and you want to manage
> suche
> data in a simple and generic way, simplification or extensions to the data-
> structure should not force you to refactor all more or less generic code-
> fragments. For example copying some entries around should not look
> different
> just because you added a dimension in your data-structure. But without
> proper value-semantics you are forced to do that, because at some point you
> will have to switch from by-value to by-reference because of limitations
> made somewhere.

I think this argument goes exactly the other way. C++ containers have 
terrible compositional behavior. Using vector<vector<T> > or 
vector<map<T> > in C++98 is suicide. C++0x fixes that by means of 
introducing rvalue references, but reference semantics obviate all that.

> *Another argument: It should be very simple (at least in C++ it is, I have
> never had problems with it, I just added the&  here and there) to handle
> references to by-value-types, but wrapping by-reference-types into by-value-
> types is really ugly, although it may be the right thing somewhere.

"here and there" is more like "every time I define a function". I mean 
that's a lot, no?

Wrapping could work either way, and after thinking about it a lot I have 
difficulty decreeing one is considerably easier/simpler than the other.

> *By-value-containers support more generic code. A copy_if on a multi-
> dimensional container should of course copy the element and not just copy
> some references, and it would be bad if the generic implementation would
> have to test if the type is by-reference, but a container supporting clone,
> eventually using clone, bothering if it is a deep clone etc. I just do not
> see a simple way to make such generic algorithms easy to implement (even
> with new language features) if by-value-types are not fully supported and
> not used for containers.

copy_if on a multidimensional container should not naively copy entire 
hyperplanes. More generally, I think that whenever an arbitrarily large 
object is to be copied, that should be explicit instead of implicit. A 
lot of focus in C++ is dedicated to making sure you don't copy the wrong 
thing.

> *Whether or not you think by-value-containers are good, a better
> alternative
> for in would be great for generic code. In C++ I can use something like
> parameter_type<T>::result choosing by-reference or by-value automatically,
> it is not very nice, but it is simply impossible with D, there are no
> reference-types, there are no ways to implement such decisions in the
> parameter-lists, and in normal code it is impossible more than ever. But
> imagine there would be a simple you could put in front of a variable or
> paramater declaration choosing by-ref/by-value automatically, lets say §,
> and of course it should be const and scope, so you would put a § before
> your
> parameters, because you may not know if type is big or not (there are
> sometimes big PODs, somebody may want to pass a FILE-object to a generic
> function or whatever), you would use a § an a read-only-foreach, and you
> would not have to bother about anything, when extracting a container-
> element
> temporarily (pivot in quicksort or whatever, you may want to sort your
> PODs,
> by-value-containers, primitives, pointers, class-objects etc.), you would
> use a § and it would be perfect. This would allow the implementation of by-
> value-containers (of course default-constructors are also required), but it
> would allow to write more generic high-quality code everywhere. In D3 this
> could even be the default for function-parameters, the C-compatible default-
> behaviour is simply nonsense.

It would be great to have D just obviate the necessity of 
parameter_type<T>::result in the first place, which is what auto ref is 
meant for (it's §).

> The User

s/The/A/ I guess ;o).

One issue that I noticed about myself and other people coming to D from 
C++ is that we expect to bring with us, along with the many things that 
make C++ great, the baggage of common worries, misgivings, and just rote 
work that we got used to.


Andrei


More information about the Digitalmars-d mailing list