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