phobos by ref or by value
Jonathan M Davis
jmdavisProg at gmx.com
Sun Dec 16 15:01:37 PST 2012
On Sunday, December 16, 2012 16:09:45 Dan wrote:
> Is there a general philosophy in D phobos on when to pass by
> value or
> reference? For instance, to find a slice using lowerBound many
> copies
> of the target item, as well as copies of items in the collection
> are
> made (see code example below). This seems unnecessary - why not
> have
> functions like:
>
> auto lowerBound(...)(V value)
>
> be:
>
> auto lowerBound(...)(ref V value)
>
> or:
>
> auto lowerBound(...)(auto ref V value)
>
> Is this a source for desire for no postblits, shallow semantics on
> copy/assignment with additional logic for copy on write
> semantics. If
> libraries in general are coded to make many copies of parameters
> it
> might be a big improvement to not have postblits. A general
> purpose
> library accessing ranges will not know the semantics of V (deep or
> shallow), so why incur the cost of copies? Certainly finding a
> lowerBound on a range of V can be done with 0 copies of elements?
>
> Is there an established philosophy?
You _don't_ take ranges by ref unless you want to alter the original, which is
almost never the case. Functions like popFrontN are the exception. And since
you _are_ going to mutate the parameter (since ranges iterate via mutation),
something like const ref would never make sense, even if it had C++'s
semantics. I'm not sure if auto ref screams at you if you try and mutate the
original, but if it doesn't, then you get problems when passing it lvalue
ranges, because they'd be being passed by ref and mutated, which you don't
want. So, auto ref makes no sense either. You pretty much always pass ranges
by value. And a range which does a deep copy when it's copied is a
fundamentally broken range anyway. It has the wrong semantics and won't
function correctly with many range-based functions. Ranges are supposed to be
a view into a range of values (possibly in a container), and copying the view
shouldn't copy the actual elements. Otherwise, you'd be doing the equivalent
of passing around a container by value, which is almost always a horrible
idea.
As for types which aren't ranges, they're almost a non-issue in Phobos. Most
functions in Phobos take either a range or a primitive type. There aren't very
many user-defined types in Phobos which aren't ranges (e.g. the types in
std.datetime), but those that aren't ranges are generally either small enough
that trying to pass by const ref or auto ref doesn't buy you much (if
anything), or they're classes, in which case, it's a non-issue. And almost
every generic function in Phobos takes a range. So, functions in Phobos almost
always take their arguments by value. They'll use ref when it's required for
the semantics of what they're doing, but auto ref on function parameters is
rare.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list