On 01/24/2017 02:03 AM, Jonathan M Davis via Digitalmars-d wrote:
> On Tuesday, January 24, 2017 00:47:31 Ali Çehreli via Digitalmars-d
wrote:
>> The problem with auto ref is that in the case of rvalues, what you have
>> is a local variable, which makes it almost given that when it's 'auto
>> ref', it better be 'auto ref const' because you don't want to mutate
>> anyway because your mutations would be lost in the case of rvalues.
>
> If you're looking to mutate the argument that's passed in, then it
needs to
> be ref. If you're looking to have a copy to mutate, then it should not be
> ref. If you don't intend to mutate it, then auto ref works just fine. It
> just doesn't prevent you from mutating anything. And if you're using auto
> ref and it's expected that the argument will be mutated, then it needs to
> make sense for the result to be thrown away as would occur with an rvalue
> argument.
Obviously, I know all of that and they are pretty complicated for new
programmers.
I just can't imagine what the semantics of a function could be. Do you
have an example? So, we're talking about a function that will mutate its
argument but the caller sometimes doesn't care. Oh, this sounds like
functions from the C era, which take null when the caller does not care.
So, is this the guideline? "Make the argument 'auto ref' when you have
something to return in addition to the return value." If so, it's
sub-obtimal because the 'auto ref' doesn't have the opportunity of
bypassing operations like the C function could:
if (arg) {
// Do expensive operation
}
If I guessed the semantics right, non-const 'auto ref' does not have
that luxury.
>> I'm under the impression (and started to write a blog post about) that
>> the following two overloads is better than 'auto ref' (const or not).
>> Given S is a struct,
>>
>> void foo(const(S)); // Takes rvalue
>> void foo(ref const(S)); // Takes lvalue
>>
>> Those two work with all kinds of S arguments: lvalue, rvalue, imuttable,
>> different kinds of member indirections, etc.
>
> I don't see why that would be better than auto ref.
Well, if I don't understand the semantics of non-const 'auto ref' then
there is only 'auto ref const' to talk about, in which case, the two
overloads are better because it's more explicit that one takes rvalue.
> It's doing exactly the
> same thing except that it's const. You're just manually doing what
auto ref
> does. And given how restrictive const is, I would be very slow to
mark much
> of anything with it unless the types are known. And if you want
const, then
> just use const auto ref. The only advantage of
>
> void foo(const(S)); // Takes rvalue
> void foo(ref const(S)); // Takes lvalue
>
> over const auto ref is that it works with virtual functions. Otherwise,
> you're just manually doing what const auto ref does - which scales
horribly
> as you add more parameters.
Yeah, the issue with non-scaling was one of the reasons why I had
stopped turning this into a blog post.
> Personally, most of the time, I simply don't worry about the
performance of
> copying. I just pass everything by value and don't use ref unless it's
> expected that the argument's value will be used and that it will be
given a
> new value as part of the call (in which case, there is no non-ref
overload).
> If profiling indicates that there's too much of a performance hit from
> copying structs around, then I'll look at using ref or auto ref for
> performance, but it's not something that I do if I don't need to. It just
> makes the code messier and more verbose - especially if you use ref
instead
> of auto ref.
>
> I also tend to not bother with const at this point. Too little works
with it
> for it to be worth it most of the time - especially since ranges
don't work
> with it. Built-in types and simple structs can work with it just
fine, but
> much beyond that becomes a bundle of pain really fast, and even simple
> structs fall flat on their face once you need a postblit constructor.
So, I
> would _not_ be in a hurry to suggest to anyone that they start using
const
> ref or const auto ref anywhere.
>
> - Jonathan M Davis
>
const is still engrained in my programming mind due to long exposure to
C and C++. I guess D is proving that it's not that essential to be
const-correct. This is similar to how private is not as strong and in
some cases public is the default.
Ali