January 27, 2013
On Sunday, 27 January 2013 at 01:23:18 UTC, Jonathan M Davis wrote:

> But it may not even end up being the case that using auto ref on non-templated functions is the solution. It may end up being something else entirely. Ignoring @safety issues, it seems to me like it would be the most straightforward solution, but there are @safety issues with ref in general that need to be addressed, and Andrei intends to address them as part of whatever happens with auto ref. That mean that auto ref gets used for non- templated functions, or it could mean something very different. I don't know what exactly the solution that Andrei is working on could entail. For all I know, it'll involve letting ref in general accept rvalues (much as I tihnk that that's a horrible idea, it _has_ been suggested before). So, without a clear idea of what we're going to want to do, merging in the pull request which makes auto ref work for non-templated functions is a bad idea. It could ultimately end up being fine, or it could end up breaking more code when the real solution gets implemented.

 Having ref accept rValues seems like a bad idea. If the source is const/immutable then it might be allowed, but more likely temporaries will be made for convertion from rValues to lValues, then passing off the temporaries. The temporaries to work right likely need to be at the top-most scope of whatever function you happen to be in; Beyond that I'm not sure how else the auto ref could be implemented safely.
January 27, 2013
On 01/26/2013 03:03 AM, Namespace wrote:

> with dmd 2.061 structs aren't lvalues anymore.

You mean, temporary struct objects are not lvalues anymore.

Ali

January 27, 2013
On Sunday, 27 January 2013 at 02:28:26 UTC, Era Scarecrow wrote:
>  Having ref accept rValues seems like a bad idea. If the source is const/immutable then it might be allowed, but more likely temporaries will be made for convertion from rValues to lValues, then passing off the temporaries. The temporaries to work right likely need to be at the top-most scope of whatever function you happen to be in; Beyond that I'm not sure how else the auto ref could be implemented safely.

I have yet to see an instance of such problem in real life, but quite frankly, I tired to argue.
January 27, 2013
On Sunday, 27 January 2013 at 04:38:44 UTC, deadalnix wrote:
> On Sunday, 27 January 2013 at 02:28:26 UTC, Era Scarecrow wrote:
>> Having ref accept rValues seems like a bad idea. If the source is const/immutable then it might be allowed, but more likely temporaries will be made for convertion from rValues to lValues, then passing off the temporaries. The temporaries to work right likely need to be at the top-most scope of whatever function you happen to be in; Beyond that I'm not sure how else the auto ref could be implemented safely.
>
> I have yet to see an instance of such problem in real life, but quite frankly, I tired to argue.

 I would have thought it was obvious. I have done before where all my work was done from a ref. Now being that i wouldn't want to duplicate my code twice, the non-ref simply forwards to the ref. auto ref may automate removing the need to explicitly forward temporaries or make them yourself; Kinda like how scope makes things easier.

 For some reason opCmp is coming to mind as a good example.

  struct S {
    //90%+ of the time this will be called,
    //so without needing to do overhead we will do our compare.
    int opCmp(ref S rhs);

    //why duplicate code? Just forward to ref
    int opCmp(S rhs) {
      return this.opCmp(rhs);
    }
  }

  S l, r;
  assert(l >= r);   //uses ref
  assert(l >= S()); //uses non-ref, forwards to ref

 I remember I came up with a good reason why the temporary should be added to the outer scope, but the reason escapes me right now.

 But as I'm thinking about the other half having ref accept rValues, I would see that acceptable if the following qualified.

 1) Must be 'const ref' or 'immutable ref', no changes means likely no special handling.
 2) No special postblit or opAssign operations
    and/or
 3) The rValue in question is a POD (Plain Old Data)

 Since likely the rValue would have to be statically known at compile-time so it could create a read-only instance in the data portion, then refer to it. By itself it seems fairly simple to add in; but I'm honestly not sure, not being able to tell them apart when you need to seems like an annoyance, likely that C++'s been dealing with.
January 27, 2013
On Sunday, 27 January 2013 at 06:13:25 UTC, Era Scarecrow wrote:
> On Sunday, 27 January 2013 at 04:38:44 UTC, deadalnix wrote:
>> On Sunday, 27 January 2013 at 02:28:26 UTC, Era Scarecrow wrote:
>>> Having ref accept rValues seems like a bad idea. If the source is const/immutable then it might be allowed, but more likely temporaries will be made for convertion from rValues to lValues, then passing off the temporaries. The temporaries to work right likely need to be at the top-most scope of whatever function you happen to be in; Beyond that I'm not sure how else the auto ref could be implemented safely.
>>
>> I have yet to see an instance of such problem in real life, but quite frankly, I tired to argue.
>
>  I would have thought it was obvious. I have done before where all my work was done from a ref. Now being that i wouldn't want to duplicate my code twice, the non-ref simply forwards to the ref. auto ref may automate removing the need to explicitly forward temporaries or make them yourself; Kinda like how scope makes things easier.

You completely fail to address the point raised.

Back on the point, quoting « Having ref accept rValues seems like a bad idea. ». D accepted it for ages, some language accept it by design (java for instance).

Now can someone show me the code ?
January 27, 2013
On Sunday, January 27, 2013 07:28:24 deadalnix wrote:
> Back on the point, quoting « Having ref accept rValues seems like a bad idea. ». D accepted it for ages, some language accept it by design (java for instance).
> 
> Now can someone show me the code ?

D's ref has never accepted rvalues. Rather, struct literals were incorrectly treated as lvalues. And Java has nothing like ref whatsoever. It has references like D's references, which are managed pointers, but that's completely different.

- Jonathan M Davis
January 27, 2013
> But it may not even end up being the case that using auto ref on non-templated
> functions is the solution. It may end up being something else entirely.
> Ignoring @safety issues, it seems to me like it would be the most
> straightforward solution, but there are @safety issues with ref in general
> that need to be addressed, and Andrei intends to address them as part of
> whatever happens with auto ref. That mean that auto ref gets used for non-
> templated functions, or it could mean something very different. I don't know
> what exactly the solution that Andrei is working on could entail. For all I
> know, it'll involve letting ref in general accept rvalues (much as I tihnk
> that that's a horrible idea, it _has_ been suggested before). So, without a
> clear idea of what we're going to want to do, merging in the pull request
> which makes auto ref work for non-templated functions is a bad idea. It could
> ultimately end up being fine, or it could end up breaking more code when the
> real solution gets implemented.
>
> - Jonathan M Davis

Ehh, so if auto ref won't be the solution, we then have auto ref for template functions and another solution for non-ref functions? I don't think that that is a smart idea and that it would be a kind of inconsistent.
January 27, 2013
On Sunday, January 27, 2013 10:47:42 Namespace wrote:
> Ehh, so if auto ref won't be the solution, we then have auto ref for template functions and another solution for non-ref functions? I don't think that that is a smart idea and that it would be a kind of inconsistent.

I don't know what solution we're going to get. And auto ref for templates actually serves another purpose other than trying to avoid unnecessary copies in that it apparently helps with attempts at perfect forwarding (though I don't remember the details, since I haven't used it for that). It's an accidental benefit of auto ref (the whole idea behind it in the first place was to deal with the const& problem), but it means that auto ref on templated functions is valuable regardless of what happens with non-templated functions. And has been pointed out, the proposed solution for auto ref and non-templated functions (that is, have the compiler create a variable to assign an rvalue to and then pass that to the function) would arguably be desirable with templated functions as well (in order to reduce code bloat), so it's arguably better to pick something other than auto ref so that it can be used for both templated and non-templated functions.

Regardless, I can't comment on what the final solution is going to be, because I don't know what it's going to be. And moving forward with an implementation that we may just throw away would be a mistake. So, we're just going to have to wait for Andrei to finish his proposal so that it can be discussed and hopefully implemented once it's been fully vetted and fleshed out.

- Jonathan M Davis
January 27, 2013
I didn't know. I thought auto ref would be the only solutions for non-template functions.
But then I think we must wait for 2 or 3 versions. With this background knowledge I will write my code twice, with and without ref. Thank you.
January 27, 2013
On 1/26/13 9:28 PM, Era Scarecrow wrote:
> Having ref accept rValues seems like a bad idea. If the source is
> const/immutable then it might be allowed, but more likely temporaries
> will be made for convertion from rValues to lValues, then passing off
> the temporaries. The temporaries to work right likely need to be at the
> top-most scope of whatever function you happen to be in; Beyond that I'm
> not sure how else the auto ref could be implemented safely.

One simple matter that has been discussed here, which I've hit only yesterday in a script was:

string lines;
...
auto r = regex(...);
auto m = lines.match(r);
// Get rid of the whole match
m.captures.popFront();
// This should be the first actual capture
auto s = m.captures.front;

The problem here is m.captures returns an rvalue. In turn that rvalue is bound (arguably incorrectly) to the reference "this" in the call to the member function popFront(). The method pops the front off the temporary, leaving the original intact. The subsequent invocation m.capture returns the value anew.

This issue is a combination of properties that return rvalues with the current (too liberal IMHO) binding of rvalues to temporaries. The latter has been a design tidbit inherited from C++, and it's been in D for a long time.


Andrei