April 09, 2012
From: "Andrej Mitrovic" <andrej.mitrovich@gmail.com>
> On 4/9/12, Steve Schveighoffer <schveiguy@yahoo.com> wrote:
>> I'll also point out that if you really want to clarify what 'a' you are
>> talking about, you can do:
>>
>> typeof(this).a = a;
> 
> Yeah, I was mainly concerned with convenience and not semantics.
> 'this.a = a' is a simple way to disambiguate between parameters and
> fields.
> 
> Side-note: I frequently use an "alias typeof(this) This;" in my
> classes so I don't have to hard-code the name of the class/struct. I
> sort of wish 'This' was implicitly given to us for every struct/class
> type. :)

vote++

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

April 09, 2012
On Monday, April 09, 2012 18:02:41 Nick Sabalausky wrote:
> From: "David Nadlinger" <code@klickverbot.at>
> 
> > On 9 Apr 2012, at 21:18, Nick Sabalausky wrote:
> >> I'm getting an ICE as a regression:
> >> 
> >> mtype.c:4472: StructDeclaration* TypeAArray::getImpl(): Assertion `impl'
> >> failed.
> >> 
> >> DustMite-int it now...
> > 
> > Try directly instantiating the AssociativeArray template – this way you should be able to see the underlying error message.
> 
> Thanks. At one point, it's trying to pass a const(MyStruct) to MyStruct.opEquals, and I forgot to keep the const overload when 2.059 is detected (ATM I only have the the new non-const non-ref opEquals when 2.059 is detected). So that's why I'm not getting that ICE in 2.058.
> 
> I'm not going to end up *also* needing "const non-ref" and/or "non-const ref" versions too, am I? I think my brain's turning to mud now...

Look at the Kenji's c omments on http://d.puremagic.com/issues/show_bug.cgi?id=7864

I expect that they apply to opEquals as well as opCmp. That being the case, the proper overloads would be

bool opEquals(const S rhs) const {}
bool opEquals(const ref S rhs) const {}

and the non-ref version should actually be able to call the ref version without causing infinite recursion. The lack of const on the non-ref version causes issues with structs which hold reference types.

All in all, this is way too messy. Bearophile's suggestion of using const auto ref will probably work though as long as you template the function (since auto ref doesn't currently work with non-templated functions).

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

On 4/9/2012 4:25 PM, Jonathan M Davis wrote:
> All in all, this is way too messy. Bearophile's suggestion of using const auto ref will probably work though as long as you template the function (since auto ref doesn't currently work with non-templated functions). - Jonathan M Davis

Templating a struct opEquals doesn't work because templates can't be installed in the TypeInfo.

I'm beginning to think that disallowing struct literals to be lvalues was a bad idea.
_______________________________________________
dmd-beta mailing list
dmd-beta@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-beta

April 09, 2012
From: "Walter Bright" <walter@digitalmars.com>
>
> On 4/9/2012 4:25 PM, Jonathan M Davis wrote:
>> All in all, this is way too messy. Bearophile's suggestion of using const auto ref will probably work though as long as you template the function (since auto ref doesn't currently work with non-templated functions). - Jonathan M Davis
>
> Templating a struct opEquals doesn't work because templates can't be installed in the TypeInfo.
>
> I'm beginning to think that disallowing struct literals to be lvalues was a bad idea.

I didn't see any of the discussion on the matter, so I might be missing somthing, but my thought ATM is I don't see why...

   foo(MyStruct());

...shouldn't be considered any different from:

   auto _tmp = MyStruct();
   foo(_tmp);

regardless of foo's signature. That's what I would intuitively expect.

Although, I suppose the "not an lvalue" restriction could help avoid accidentally passing literals to something like fooInPlace and result in an accidental no-op. But then, not everything with a ref arg is intended to be a xxxInPlace function anyway. For example, opCmp.

IIRC, I think someone mentioned here earlier about it being to make structs consistent with int/etc. But (possibly crazy idea here) maybe that just means that the consitency should just work the other way: That maybe int literals should be usable as "ref int" args (and imply creation of a throwaway temp var). The "ref" *does* imply "in AND out", and if the caller doesn't care about the output, then why not allow an implicit throwaway temp?

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...?)

Anyway, my $0.02, FWIW.

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

April 09, 2012
On Monday, April 09, 2012 22:32:53 Nick Sabalausky wrote:
> From: "Walter Bright" <walter@digitalmars.com>
> 
> > On 4/9/2012 4:25 PM, Jonathan M Davis wrote:
> >> All in all, this is way too messy. Bearophile's suggestion of using const auto ref will probably work though as long as you template the function (since auto ref doesn't currently work with non-templated functions). - Jonathan M Davis
> > 
> > Templating a struct opEquals doesn't work because templates can't be installed in the TypeInfo.
> > 
> > I'm beginning to think that disallowing struct literals to be lvalues was a bad idea.
> 
> I didn't see any of the discussion on the matter, so I might be missing somthing, but my thought ATM is I don't see why...
> 
>     foo(MyStruct());
> 
> ...shouldn't be considered any different from:
> 
>     auto _tmp = MyStruct();
>     foo(_tmp);
> 
> regardless of foo's signature. That's what I would intuitively expect.
> 
> Although, I suppose the "not an lvalue" restriction could help avoid accidentally passing literals to something like fooInPlace and result in an accidental no-op. But then, not everything with a ref arg is intended to be a xxxInPlace function anyway. For example, opCmp.
> 
> IIRC, I think someone mentioned here earlier about it being to make structs consistent with int/etc. But (possibly crazy idea here) maybe that just means that the consitency should just work the other way: That maybe int literals should be usable as "ref int" args (and imply creation of a throwaway temp var). The "ref" *does* imply "in AND out", and if the caller doesn't care about the output, then why not allow an implicit throwaway temp?
> 
> 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...?)
> 
> Anyway, my $0.02, FWIW.

If struct literals are lvalues, then

void func(const ref S s) {...}
S foo() {...}

func(S(1)); //compiles
func(foo()); //fails

S(1) is a temporary just like the value returned by foo. Why on earth would it be an lvalue. It represents neither a variable nor a memory address. I believe that the discussion of struct literals being rvalues was near unanimous save for Walter. But I'd have to go digging to find the discussion.

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

April 09, 2012

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.
_______________________________________________
dmd-beta mailing list
dmd-beta@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-beta

April 09, 2012
On 4/9/12 9:37 PM, Jonathan M Davis wrote:
> S(1) is a temporary just like the value returned by foo. Why on earth would it
> be an lvalue. It represents neither a variable nor a memory address.

Same here. Blaming rvalueness of temporaries for this matter would be a mistake. The problem is elsewhere. Please don't revert the right decision.

Thanks,

Andrei

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

April 09, 2012
On Apr 9, 2012, at 10:32 PM, "Nick Sabalausky" <bus_dmdbeta@semitwist.com> wrote:

> From: "Walter Bright" <walter@digitalmars.com>
>> 
>> On 4/9/2012 4:25 PM, Jonathan M Davis wrote:
>>> All in all, this is way too messy. Bearophile's suggestion of using const auto ref will probably work though as long as you template the function (since auto ref doesn't currently work with non-templated functions). - Jonathan M Davis
>> 
>> Templating a struct opEquals doesn't work because templates can't be installed in the TypeInfo.
>> 
>> I'm beginning to think that disallowing struct literals to be lvalues was a bad idea.
> 
> I didn't see any of the discussion on the matter, so I might be missing somthing, but my thought ATM is I don't see why...
> 
>   foo(MyStruct());
> 
> ...shouldn't be considered any different from:
> 
>   auto _tmp = MyStruct();
>   foo(_tmp);
> 
> regardless of foo's signature. That's what I would intuitively expect.
> 
> Although, I suppose the "not an lvalue" restriction could help avoid accidentally passing literals to something like fooInPlace and result in an accidental no-op. But then, not everything with a ref arg is intended to be a xxxInPlace function anyway. For example, opCmp.
> 
> IIRC, I think someone mentioned here earlier about it being to make structs consistent with int/etc. But (possibly crazy idea here) maybe that just means that the consitency should just work the other way: That maybe int literals should be usable as "ref int" args (and imply creation of a throwaway temp var). The "ref" *does* imply "in AND out", and if the caller doesn't care about the output, then why not allow an implicit throwaway temp?

From a safety perspective, passing strict literals as "const ref" is fine. There is no output to discard. I have a vague impression that the restriction was put in place to allow some kind of optimization. I bet it's discussed in TDPL somewhere...
_______________________________________________
dmd-beta mailing list
dmd-beta@puremagic.com
http://lists.puremagic.com/mailman/listinfo/dmd-beta

April 09, 2012
On Monday, April 09, 2012 17:24:17 Walter Bright wrote:
> On 4/9/2012 4:25 PM, Jonathan M Davis wrote:
> > All in all, this is way too messy. Bearophile's suggestion of using const auto ref will probably work though as long as you template the function (since auto ref doesn't currently work with non-templated functions). - Jonathan M Davis
> Templating a struct opEquals doesn't work because templates can't be installed in the TypeInfo.
> 
> I'm beginning to think that disallowing struct literals to be lvalues was a bad idea.

The issue isn't that struct literals are now rvalues. The problem exists regardless of that. If all you have is

bool opEquals(const ref S rhs) {...}
S foo() {...}

then

auto s = S(1);
assert(s == s); //compiles
assert(s == foo()); //fails to compile

If you make struct literals lvalues, then this will compile

assert(s == S(1));

and if they're rvalues, it won't. But the problem with rvalues remains regardless, and from what I recall of the discussions of struct literals, most everyone thought that they should be rvalues. It's incredibly inconsistent IMHO to have struct literals be lvalues whereas all other temporaries are rvalues. From what I can tell, it just causes confusion - especially when C++ programmers expect const ref to work with temporaries.

The core problem is the fact that const ref requires an lvalue. If it were like C++ and took temporaries, then we wouldn't have this problem. The solution that we seem to have gone with in lieu of that is to introduce auto ref, but as long as that only works with templated functions, it doesn't solve this issue.

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

April 09, 2012
On 4/9/12 9:32 PM, Nick Sabalausky wrote:
> foo(MyStruct());
>
> ...shouldn't be considered any different from:
>
> auto _tmp = MyStruct();
> foo(_tmp);
>
> regardless of foo's signature. That's what I would intuitively expect.

They are different because in the latter case _tmp may or may not be used, whereas in the former the value is disposable.


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