April 09, 2012
On Monday, April 09, 2012 23:28:27 Walter Bright wrote:
> On 4/9/2012 10:51 PM, Jonathan M Davis wrote:
> > I really don't care how it's implemented for not-templated functions. It can be the outright equivalent of C++'s const& for all I care. But without auto ref on non-templated functions, we're forced to duplicate any non-templated function which takes const ref.
> 
> Let's say the compiler auto-generates the following:
> 
>     void foo(T t) { foo(t); }
> 
> in case it sees:
> 
>      void foo(ref T t) { ... }
> 
> I don't think that's a solution at all. It's just a roundabout way for the compiler to generate a temporary anyway. Nothing has been gained.

It wouldn't be a good idea for every single ref to end up with a duplicated function like that, since if ref is what was actually intended, then the code would behave incorrectly. With auto ref, at least the programmer is signalling that that's what they mean. On the whole, I don't think that it's all that big a deal with ref, since when you use ref, you really want a ref. It's const ref that's the problem.

As it stands, if you use const ref, you have to create an extra function or be forced to create extraneous variables just to call the function, and that's not at all friendly. If auto ref actually did what it was intended to do and made it so that you could pass by either ref or non-ref essentially like what occurs with C++'s const&, then you wouldn't have to be duplicating functions, and it would be _much_ more programmer-friendly. Sure, it would be nice if that could be done without the compiler duplicating the function, but having

void foo(auto ref T t) {...}

become

void foo(T t) { foo(t); }
void foo(ref T t) { ... }

and have

void foo(const auto ref T t) {...}

become

void foo(const T t) { foo(t); }
void foo(const ref T t) {...}

or maybe even have

void foo(auto ref T t) {...}

become

void foo(const T t) { foo(t); }
void foo(const ref T t) {...}

then it would be a big step forward, because you wouldn't have to be duplicating pretty much every const ref function like you do no. Even if it's just a "roundabout way for the compiler to generate a temporary," it's still a huge boon to usability. It would be nice if there were another way to do it without having the compiler duplicate the function like that, but lacking a proposal which would make auto ref work in a better way, I think that it's the way to go.

- Jonathan M Davis
_______________________________________________
dmd-beta mailing list
dmd-beta@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-beta

April 10, 2012
From: "Walter Bright" <walter@digitalmars.com>
>
> On 4/9/2012 10:51 PM, Jonathan M Davis wrote:
>> I really don't care how it's implemented for not-templated functions. It can be the outright equivalent of C++'s const& for all I care. But without auto ref on non-templated functions, we're forced to duplicate any non-templated function which takes const ref.
>
> Let's say the compiler auto-generates the following:
>
>    void foo(T t) { foo(t); }
>
> in case it sees:
>
>     void foo(ref T t) { ... }
>

No, not when it sees:

    void foo(ref T t) { ... }

It's when it sees:

    void foo(auto ref T t) { ... }

_______________________________________________
dmd-beta mailing list
dmd-beta@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-beta

April 10, 2012
On 4/10/12 1:28 AM, Walter Bright wrote:
> Let's say the compiler auto-generates the following:
>
> void foo(T t) { foo(t); }
>
> in case it sees:
>
> void foo(ref T t) { ... }
>
> I don't think that's a solution at all. It's just a roundabout way for
> the compiler to generate a temporary anyway. Nothing has been gained.

I agree.

To answer the question about why rvalue -> const& has been a mistake in C++: the history is, C++ had trouble with defining copy constructors. The simple idea would be

T(T source);

but this didn't quite work because of the infinite regression:

T a;
T b(a); // recurses forever

Going with

T(T& source);

would make this code nonworking:

T fun();
T a(fun());

because C++ does not allow rvalue to modifiable conversion on correctness grounds.

Now, the solution C++ chose to solve this was to make const& a universal sink for rvalues, modifiable lvalues, and const lvalues altogether, and the copy constructor became:

T(const T&);

That solves the infinite regression nicely but at the cost of introducing an unnatural conversion rule that ultimately disabled this code:

void fun(T);
void fun(T&);
void fun(const T&);

The mechanisms through which these overloads were deemed illegal are complex and non-obvious; practically it was a sheer consequence of the fact that overloading rules were already difficult and nobody figured that the rvalue overload was necessary, so it fell by the wayside.

(We've seen similar subtle issues arising with hashtables - Teoh tried to put hashes in a library and hit a maze of subtle special cases that work for the built-in type but not for library one simply because no attention was paid to that.)

So now C++98 got standardized, and before long it was clear that unnecessary copies were a large liability. It was, however, impossible to introduce a new overload rule without breaking some code that counted on it. That prompted the entire rvalue references work, which is a maze of rules and special cases designed to navigate the wreck created by the rvalue -> const& trivial conversion.


Andrei
_______________________________________________
dmd-beta mailing list
dmd-beta@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-beta

April 10, 2012
On 4/10/12 1:41 AM, Nick Sabalausky wrote:
> No, not when it sees:
>
> void foo(ref T t) { ... }
>
> It's when it sees:
>
> void foo(auto ref T t) { ... }

Yah, I think this could work, but I'm not 100% sure.

So auto ref in a template function means "generate code appropriately with or without ref".

Now, if a function is NOT a template, we could have a completely different approach to the same issue. In that context, "auto ref" might mean "I don't care, just accept references to rvalues too!"

That would take care of the matter. It's different from the C++ rule because the user can still overload on ref and rvalue if they need the distinction, and "auto ref" offers an explicit (not implicit) route to achieving "I don't care".


Andrei


_______________________________________________
dmd-beta mailing list
dmd-beta@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-beta

April 10, 2012
If I understand correctly (and I very well might not), the idea is that auto ref is *always* ref, so only one function is generated.  The main difference between auto ref and ref is that ref doesn't allow rvalues.  Saying auto ref is basically like saying to the compiler: "yeah, I know it's an rvalue, still pass it as ref".


If that's correct, I think the way to look at it is these three situations:

1. I want to change the value, and/or I want to disallow rvalues: use ref
2. I want to pass by reference because the struct is large: use auto ref (includes rvalues), possibly const as well.

3. I want to optimize passing large structs for both rvalues and lvalues: use two overloads, one with const ref, one by value.

Andrei, I hate to ask this, because I feel very confused from all the statements you have previously made, but could you explain this again?

To be honest, if what I've said is correct, it still sounds so clunky and awkward...

-Steve




>________________________________
> From: Walter Bright <walter@digitalmars.com>
>To: Discuss the dmd beta releases for D <dmd-beta@puremagic.com>
>Sent: Monday, April 9, 2012 11:55 PM
>Subject: Re: [dmd-beta] D 2.059 beta 4
> 
>
>
>On 4/9/2012 7:44 PM, Jonathan M Davis wrote:
>> On Monday, April 09, 2012 19:40:43 Walter Bright wrote:
>>> On 4/9/2012 7:32 PM, Nick Sabalausky wrote:
>>>> Although, if there really is good merit to struct lits not veing lvalues, then maybe all we need is to wait until "auto ref" is usable for non-templates? (If that would even be possible...?)
>>> Not possible, as the binary ABI would be different.
>> It was my understanding that the auto ref was supposed to work with non- templated functions - at least what Andrei proposed was - but that you misunderstood that and made it only work with templates. And as long as it only works with templates, it's usefulness is very limited. opEquals would be a _prime_ case for where it would be useful.
>>
>
>How could that possibly work for the same function, considering that the code for each would be quite different, including the calling code?
>
>_______________________________________________
>dmd-beta mailing list
>dmd-beta@puremagic.com
>http://lists.puremagic.com/mailman/listinfo/dmd-beta
>
>
>

April 10, 2012
With the recently incorporated fix, dcollections now builds and passes all unit tests.  Thanks!

-Steve




>________________________________
> From: Steve Schveighoffer <schveiguy@yahoo.com>
>To: Steve Schveighoffer <schveiguy@yahoo.com>; Discuss the dmd beta releases for D <dmd-beta@puremagic.com>
>Sent: Monday, April 9, 2012 11:59 AM
>Subject: Re: [dmd-beta] D 2.059 beta 4
> 
>
>I can confirm that Kenji's fix works (oh, I guess you already merged it, cool :)
>
>
>
>Also, I have found the other issue: http://d.puremagic.com/issues/show_bug.cgi?id=7873
>
>-Steve
>
>
>
>
>
>
>>________________________________
>> From: Steve Schveighoffer <schveiguy@yahoo.com>
>>To: Discuss the dmd beta releases for D <dmd-beta@puremagic.com>
>>Sent: Monday, April 9, 2012 11:20 AM
>>Subject: Re: [dmd-beta] D 2.059 beta 4
>> 
>>
>>This still isn't compiling dcollections.
>>
>>
>>Kenji has posted a fix for http://d.puremagic.com/issues/show_bug.cgi?id=7811
>>
>>
>>I'm going to test with this and see if I can determine what the underlying issue is (of course, 7811 should still be fixed!)
>>
>>
>>-Steve
>>
>>
>>
>>
>>>________________________________
>>> From: Walter Bright <walter@digitalmars.com>
>>>To: Discuss the dmd beta releases for D <dmd-beta@puremagic.com>
>>>Sent: Monday, April 9, 2012 3:01 AM
>>>Subject: [dmd-beta] D 2.059 beta 4
>>> 
>>>
>>>http://ftp.digitalmars.com/dmd2beta.zip
>>>_______________________________________________
>>>dmd-beta mailing list
>>>dmd-beta@puremagic.com
>>>http://lists.puremagic.com/mailman/listinfo/dmd-beta
>>>
>>>
>>>
>>_______________________________________________
>>dmd-beta mailing list
>>dmd-beta@puremagic.com
>>http://lists.puremagic.com/mailman/listinfo/dmd-beta
>>
>>
>
>

April 10, 2012

On 4/10/2012 3:59 AM, Steve Schveighoffer wrote:
> If I understand correctly (and I very well might not), the idea is that auto ref is *always* ref, so only one function is generated.

No. Two functions are generated.

>   The main difference between auto ref and ref is that ref doesn't allow
> rvalues.  Saying auto ref is basically like saying to the compiler: "yeah, I
> know it's an rvalue, still pass it as ref".
>
> If that's correct, I think the way to look at it is these three situations:
>
> 1. I want to change the value, and/or I want to disallow rvalues: use ref
> 2. I want to pass by reference because the struct is large: use auto ref
> (includes rvalues), possibly const as well.
> 3. I want to optimize passing large structs for both rvalues and lvalues: use
> two overloads, one with const ref, one by value.
>
> Andrei, I hate to ask this, because I feel very confused from all the statements you have previously made, but could you explain this again?
>
> To be honest, if what I've said is correct, it still sounds so clunky and awkward...
>
> -Steve
>
>     --------------------------------------------------------------------------------
>     *From:* Walter Bright <walter@digitalmars.com>
>     *To:* Discuss the dmd beta releases for D <dmd-beta@puremagic.com>
>     *Sent:* Monday, April 9, 2012 11:55 PM
>     *Subject:* Re: [dmd-beta] D 2.059 beta 4
>
>
>
>     On 4/9/2012 7:44 PM, Jonathan M Davis wrote:
>     > On Monday, April 09, 2012 19:40:43 Walter Bright wrote:
>     >> On 4/9/2012 7:32 PM, Nick Sabalausky wrote:
>     >>> Although, if there really is good merit to struct lits not veing lvalues,
>     >>> then maybe all we need is to wait until "auto ref" is usable for
>     >>> non-templates? (If that would even be possible...?)
>     >> Not possible, as the binary ABI would be different.
>     > It was my understanding that the auto ref was supposed to work with non-
>     > templated functions - at least what Andrei proposed was - but that you
>     > misunderstood that and made it only work with templates. And as long as it
>     > only works with templates, it's usefulness is very limited. opEquals
>     would be
>     > a _prime_ case for where it would be useful.
>     >
>
>     How could that possibly work for the same function, considering that the code
>     for each would be quite different, including the calling code?
>
>     _______________________________________________
>     dmd-beta mailing list
>     dmd-beta@puremagic.com <mailto:dmd-beta@puremagic.com>
>     http://lists.puremagic.com/mailman/listinfo/dmd-beta
>
>
>
>
> _______________________________________________
> dmd-beta mailing list
> dmd-beta@puremagic.com
> http://lists.puremagic.com/mailman/listinfo/dmd-beta


April 10, 2012
On 9 apr 2012, at 23:24, Andrej Mitrovic wrote:

> On 4/9/12, Walter Bright <walter@digitalmars.com> wrote:
>> I believe the error message is correct.
> 
> I don't know about that. in TDPL p197 it says:
> "If you use an object instead of the class name when accessing a
> static member, that's fine, too.:
> auto c = (new Widget).someStaticMember"
> 
> It would naturally follow that using 'this' for static members would be ok as well. Why break code now?

I know that is currently allowed but I don't think it should be allowed. This would make it possible to overload on static, i.e.

class Foo
{
    static void foo () {}
    void foo () {}
}

-- 
/Jacob Carlborg

_______________________________________________
dmd-beta mailing list
dmd-beta@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-beta

April 10, 2012

On 4/10/2012 4:11 AM, Steve Schveighoffer wrote:
> With the recently incorporated fix, dcollections now builds and passes all unit tests.  Thanks!
>

Welcs!


April 10, 2012
On 4/10/12 11:25 AM, Walter Bright wrote:
> On 4/10/2012 3:59 AM, Steve Schveighoffer wrote:
>> If I understand correctly (and I very well might not), the idea is
>> that auto ref is *always* ref, so only one function is generated.
>
> No. Two functions are generated.

That is correct. In the proposal I sketched last night, for templates it's possible to only generate one function and simply loosen the requirement that the caller has an lvalue.

Andrei

_______________________________________________
dmd-beta mailing list
dmd-beta@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-beta