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