December 26, 2012
> On 2012-12-25 15:11, Andrei Alexandrescu wrote:
>> Yes, that does work and is easy to implement.

This also solves the problem of taking the address of the `auto ref` function or method. Two birds with one stone.
December 26, 2012
> Yes, that does work and is easy to implement.
>
> Andrei

And why isnt it in 2.061? ;)
December 26, 2012
On Tuesday, 25 December 2012 at 14:09:13 UTC, Andrei Alexandrescu wrote:
> On 12/25/12 12:34 AM, Zhenya wrote:
>> On Tuesday, 25 December 2012 at 01:40:16 UTC, Peter Alexander wrote:
>>> On Tuesday, 25 December 2012 at 00:56:44 UTC, Peter Alexander wrote:
>>>> On Monday, 24 December 2012 at 17:40:54 UTC, Jonathan M Davis wrote:
>>>>> And if that doesn't work, can we simply make it so that the compiler
>>>>> automatically creates a variable when you pass an rvalue to a
>>>>> non-templated
>>>>> auto ref function?
>>>>
>>>> I don't see any problems with this, but I admittedly haven't thought
>>>> too much about it.
>>>
>>> If there are no problems with this way, then what I want to know is
>>> why the template version of auto ref wasn't implemented this way. The
>>> way auto ref is currently implemented for templates is a bit of a mess.
>> Maybe it's difficult to generate both versions because for the function
>> like this
>>
>> void foo(auto ref S s1,auto ref S s2,...,auto ref s10)
>>
>> compiler should generate 2^10 versions of function foo.
>
> The compiler will only generate as many versions as there are compatible calls.
>
> Andrei

In such a case, this is incompatible with virtual method.
December 26, 2012
On Tuesday, 25 December 2012 at 14:11:14 UTC, Andrei Alexandrescu wrote:
> On 12/25/12 5:36 AM, Jonathan M Davis wrote:
>> On Tuesday, December 25, 2012 11:14:40 Namespace wrote:
>>>> What does this generate?
>>>>
>>>> auto foo(auto ref S a, auto ref S b, auto ref S c, auto ref S
>>>> d) { ... }
>>>>
>>>> 16 different functions, one for each combination? Sounds like a
>>>> bad idea.
>>>
>>> In my opinion, this should produce only two functions:
>>> #1: auto foo(ref S a, ref S b, ref S c, ref S d) { ... }
>>> #2: auto foo(S a, S b, S c, S d) { ... }
>>
>> So, you'd take the performance hit of copying all of your function arguments
>> simply because one of them was an rvalue?
>>
>> No. I think that Peter's point shows exactly why this is a bad idea.
>>
>> However, creating only one version of the function which takes all refs and
>> specifcally creating variables underneath the hood for any rvalues so that
>> they can be passed to the function still seems like it could work.
>
> Yes, that does work and is easy to implement.
>
> Andrei

Sound like the wayt o go for me. But is ato ref needed in such case ? Why not simply allow ref to behave that way ?
December 26, 2012
On Wednesday, December 26, 2012 23:02:25 deadalnix wrote:
> Sound like the wayt o go for me. But is ato ref needed in such case ? Why not simply allow ref to behave that way ?

Because there's a very large difference between a function intended to take arguments by ref and one where you don't care. For instance, what if popFrontN suddenly accepted rvalues? Using it with rvalues would do nothing. We had problems with std.conv.parse precisely because there was a compiler bug that allowed you to pass string literals to it in spite of the fact that it takes its argument by ref and needs to mutate its argument.

With auto ref, you're specifically saying that you don't care whether the function is given an lvalue or rvalue. You just want it to avoid unnecessary copies. That's very different. And auto ref then not only then protects you from cases of passing an rvalue to a function when it needs an lvalue, but it makes it clear in the function signature which is expected.

- Jonathan M Davis
December 27, 2012
On Wednesday, 26 December 2012 at 22:52:29 UTC, Jonathan M Davis wrote:
> On Wednesday, December 26, 2012 23:02:25 deadalnix wrote:
>> Sound like the wayt o go for me. But is ato ref needed in such
>> case ? Why not simply allow ref to behave that way ?
>
> Because there's a very large difference between a function intended to take
> arguments by ref and one where you don't care. For instance, what if popFrontN
> suddenly accepted rvalues? Using it with rvalues would do nothing. We had
> problems with std.conv.parse precisely because there was a compiler bug that
> allowed you to pass string literals to it in spite of the fact that it takes
> its argument by ref and needs to mutate its argument.
>

That is a const bug not a ref bug.

> With auto ref, you're specifically saying that you don't care whether the
> function is given an lvalue or rvalue. You just want it to avoid unnecessary
> copies. That's very different. And auto ref then not only then protects you
> from cases of passing an rvalue to a function when it needs an lvalue, but it
> makes it clear in the function signature which is expected.
>
> - Jonathan M Davis

I suspect making the distinction is complicating uselessly the language for a benefit that isn't really clear.
December 27, 2012
On Thursday, December 27, 2012 06:26:38 deadalnix wrote:
> On Wednesday, 26 December 2012 at 22:52:29 UTC, Jonathan M Davis
> 
> wrote:
> > On Wednesday, December 26, 2012 23:02:25 deadalnix wrote:
> >> Sound like the wayt o go for me. But is ato ref needed in such case ? Why not simply allow ref to behave that way ?
> > 
> > Because there's a very large difference between a function
> > intended to take
> > arguments by ref and one where you don't care. For instance,
> > what if popFrontN
> > suddenly accepted rvalues? Using it with rvalues would do
> > nothing. We had
> > problems with std.conv.parse precisely because there was a
> > compiler bug that
> > allowed you to pass string literals to it in spite of the fact
> > that it takes
> > its argument by ref and needs to mutate its argument.
> 
> That is a const bug not a ref bug.

No, it's not. A function which takes its argument by ref is specifically intended to mutate its argument, otherwise it wouldn't take the argument by ref. Allowing such a parameter to be passed an rvalue makes it so that the function does not do what it's intended to do and will easily cause bugs.

C++ made it so that const& would accept rvalues with the idea that if it were const, then you obviously didn't want to mutate the argument, and you could then use it as a means to avoid unnecessary copies. But with how restrictive const is in D, we really should have a means of declaring a function parameter such that it's intended to avoid unnecessary copies but isn't necessarily const and is obviously not intended to mutate the original (though as long as the parameter isn't const, mutation is obviously still a possibility, and const is required to guarantee that that doesn't happen - _that_ could be a const-related bug). But allowing ref functions to accept rvalues is an incredibly bad idea, because it's mixing two very different idioms - taking an argument by ref in order to mutate that argument and possibly taking an argument by ref in order to avoid a copy. It never makes sense to take an rvalue by ref. rvalue arguments need to use moves, not ref.

The suggestion of creating a variable with limited scope which rvalues are assigned to with auto ref allows for you to only have one function overload and yet clearly separates it from functions which are intended to mutate their arguments.

> > With auto ref, you're specifically saying that you don't care
> > whether the
> > function is given an lvalue or rvalue. You just want it to
> > avoid unnecessary
> > copies. That's very different. And auto ref then not only then
> > protects you
> > from cases of passing an rvalue to a function when it needs an
> > lvalue, but it
> > makes it clear in the function signature which is expected.
> > 
> > - Jonathan M Davis
> 
> I suspect making the distinction is complicating uselessly the language for a benefit that isn't really clear.

Well, I strongly disagree. I think that making ref accept rvalues is just begging for bugs. Not even C++ allowed that. They restricted it specifically to const&.

- Jonathan M Davis
December 27, 2012
On Thursday, 27 December 2012 at 05:53:23 UTC, Jonathan M Davis wrote:
> No, it's not.

The example IS a const bug and have nothing to do with ref. You get a mutable reference from a literal, which is immutable in the first place.

> A function which takes its argument by ref is specifically
> intended to mutate its argument, otherwise it wouldn't take the argument by
> ref. Allowing such a parameter to be passed an rvalue makes it so that the
> function does not do what it's intended to do and will easily cause bugs.
>

A function can use ref argument for performance reasons.

> C++ made it so that const& would accept rvalues with the idea that if it were
> const, then you obviously didn't want to mutate the argument, and you could
> then use it as a means to avoid unnecessary copies. But with how restrictive
> const is in D, we really should have a means of declaring a function parameter
> such that it's intended to avoid unnecessary copies but isn't necessarily
> const and is obviously not intended to mutate the original (though as long as
> the parameter isn't const, mutation is obviously still a possibility, and
> const is required to guarantee that that doesn't happen - _that_ could be a
> const-related bug). But allowing ref functions to accept rvalues is an
> incredibly bad idea, because it's mixing two very different idioms - taking an
> argument by ref in order to mutate that argument and possibly taking an
> argument by ref in order to avoid a copy. It never makes sense to take an
> rvalue by ref. rvalue arguments need to use moves, not ref.
>

I have read this argument many any times, but still have to experience it in actual code.

But, thinking about it, isn't the need for an auto ref type necessary more than annotating every single function argument with ref/auto ref ?
January 02, 2013
> "Can we simply make it so that the compiler automatically creates a variable when you pass an rvalue to a non-templated auto ref function?"
>
> So non-template auto ref parameters are just like ref parameters, except they will automatically convert rvalues to lvalues on call by creating a local variable. Normal ref parameters will still need lvalues.

I made a pull requests that implements this:

https://github.com/D-Programming-Language/dmd/pull/1428

I don't have a good knowledge of the DMD cod base, so there could be some problems with this that I am not aware of, but it does seem to work.
January 18, 2013
On Wednesday, 26 December 2012 at 22:52:29 UTC, Jonathan M Davis wrote:
> On Wednesday, December 26, 2012 23:02:25 deadalnix wrote:
>> Sound like the way to go for me. But is auto ref needed in such
>> case ? Why not simply allow ref to behave that way ?
>
> Because there's a very large difference between a function intended to take arguments by ref and one where you don't care.

>> With auto ref, you're specifically saying that you don't care whether the function is given an lvalue or rvalue. You just want it to avoid unnecessary copies. That's very different. And auto ref then not only then protects you from cases of passing an rvalue to a function when it needs an lvalue, but it makes it clear in the function signature which is expected.

 Not to bring back something that might be considered closed, But is auto ref going to be allowed for non-template functions in an upcoming version? There's plenty of times I'd like to use ref when possible but don't want to write a forwarding function converting non-ref to ref.