improvement request - enabling by-value-containers
Jonathan M Davis
jmdavisProg at gmx.com
Wed Dec 8 14:45:35 PST 2010
On Wednesday, December 08, 2010 14:14:57 Simon Buerger wrote:
> For Every lib its a design descision if containers should be value- or
> reference-types. In C++ STL they are value-types (i.e. the
> copy-constructor does a real copy), while in tango and phobos the
> descision was to go for reference-types afaik, but I would like to be
> able to write value-types too, which isn't possible (in a really good
> way) currently. Following points would need some love (by-value
> containers are probably not the only area, where these could be useful)
It's extremely rare in my experience that it makes any sense to copy a container
on a regular basis. Having an easy means of creating a deep copy of a container
or copying the elements from one container to another efficiently would be good,
but having containers be value types is almost always a bad idea. It's just not
a typical need to need to copy containers - certainly not enough to have them be
copied just because you passed them to a function or returned them from one. I
think that reference types for containers is very much the correct decision.
There should be good ways to copy containers, but copying shouldn't be the
default for much of anything in the way of containers.
> (1) Allow default-constructors for structs
> I don't see a reason, why "this(int foo)" is allowed, but "this()" is
> not. There might be some useful non-trivial init to do for complex
> structs.
It has to do with the init property. It has to be known at compile-time for all
types. For classes, that's easy because it's null, but for structs, that's what
all of their member variables are directly initialized to. If you add a default
constructor, then it would have to be to whatever that constructed them to,
which would shift it from compile time to runtime. It should be possible to have
default constructors which are definitely limited in a number of ways (like
having to be nothrow and possibly pure), but that hasn't been sorted out, and
even if it is, plenty of cases where people want default constructors still
wouldn't likely work. It just doesn't work to have default constructors which
can run completely arbitrary code. You could get exceptions thrown in weird
places and a variety of other problems which we can't have in situations where
init is used. Hopefully, we'll get limited default constructors at some point,
but it hasn't happened yet (and probably won't without a good proposal that
deals with all of the potentiall issues), and regardless, it will never be as
flexible as what C++ does. It's primarily a side effect of insisting that all
variables be default initialized if they're not directly initialized.
> (2) const parameters by reference
> If a parameter to a function is read-only, the right notion depends on
> the type of that parameter. I.e. "in" for simple stuff like ints, and
> "ref const" for big structures. Using "in" for big data implies a
> whole copy, even though it's constant, and using "ref const" for
> simple types is a useless indirection. This is a problem for generic
> code, when the type is templated, because there is now way to switch
> between "in" and "ref const" with compile-time-reflection.
>
> Solution one: make "ref" a real type-constructor, so you could do the
> following (this is possible in C++):
>
> static if(is(T == struct))
> alias ref const T const_type;
> else
> alias const scope T const_type;
> // "const scope" is (currently) equivalent to "in"
> void foo(const_type x)
>
> Solution two: let "in" decide wheather to pass by reference or value,
> depending on the type. Probably the better solution cause the
> programmer dont need to care of the descision himself anymore.
I think that auto ref is supposed to deal with some of this, but it's buggy at
the moment, and I'm not sure exactly what it's supposed to do. There was some
discussion on this one in a recent thread.
> (3) make foreach parameters constant
> when you do "foreach(x;a)" the x value gets copied in each iteration,
> once again, that matters for big types especially when you have a
> copy-constructor. Current work-around is prepending "ref": nothing
> gets copied, but the compiler wont know it is meant to be read-only.
> Solution: either allow "ref const" or "in" in foreach. Or you could
> even make x default to constant if not stated as "ref" explicitly.
> Last alternative seems logical to me, but it may break existing code.
I'd hate to see foreach variables be const by default. That would be overly
limiting and would definitely break a lot of code. Making ref const work properly
would be good (I think that it works in at least some cases) for structs that
you don't want to be copied but wouldn't be all that useful otherwise. Nothing
in D is const by default, and I think that making anything const by default
would clash with the rest of the language. Particularly since then how would you
make it mutable? No, it should be possible to have const refs to structs for
foreach variables, but it shouldn't be the default. The language as a whole just
does not support that.
- Jonathan M Davis
More information about the Digitalmars-d
mailing list