www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Smart references

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
I'm investigating D's ability to define and use smart references. Per 
the skeleton at http://dpaste.dzfl.pl/9d752b1e9b4e, lines:

#6: You can't default-initialize a ref.

#7: You can't copy a ref - copying should mean copying the object itself.

#9: Per this example I'm hooking a reference with an Owner. The 
reference hooks calls to opAddRef and opRelease in the owner.

#23: Assigning the reference really assigns the referred.

#28: A reference is a subtype of ref T. Most operations against the 
reference will be automatically forwarded to the underlying object, by 
reference ("ref" is important here).

As unittests show, things work quite nicely. There are a few things that 
don't:

#70: Attempting to copy a reference fails on account of the disabled 
postblit. There should be a way to tell the compiler to automatically 
invoke alias this and create a copy of that guy.

#81: Moving from a reference works by moving the Ref object. There 
should be a way to tell the compiler that moving should really move the 
payload around.

There are a couple other issues not represented in the unittest, for 
example related to template deduction. In a perfect world, Ref would 
masquerade (aside from having a different layout, ctor, and dtor) as an 
lvalue of type T.

But in fact I think solving the matters above would go a long way toward 
making smart references nicely usable. Although my example is centered 
on reference counting an owner, there are other uses of smart 
references. Are all these worth changing the language?


Andrei
Mar 11 2015
next sibling parent reply Rikki Cattermole <alphaglosined gmail.com> writes:
On 12/03/2015 9:33 a.m., Andrei Alexandrescu wrote:
 I'm investigating D's ability to define and use smart references. Per
 the skeleton at http://dpaste.dzfl.pl/9d752b1e9b4e, lines:

 #6: You can't default-initialize a ref.

 #7: You can't copy a ref - copying should mean copying the object itself.

 #9: Per this example I'm hooking a reference with an Owner. The
 reference hooks calls to opAddRef and opRelease in the owner.

 #23: Assigning the reference really assigns the referred.

 #28: A reference is a subtype of ref T. Most operations against the
 reference will be automatically forwarded to the underlying object, by
 reference ("ref" is important here).

 As unittests show, things work quite nicely. There are a few things that
 don't:

 #70: Attempting to copy a reference fails on account of the disabled
 postblit. There should be a way to tell the compiler to automatically
 invoke alias this and create a copy of that guy.

 #81: Moving from a reference works by moving the Ref object. There
 should be a way to tell the compiler that moving should really move the
 payload around.

 There are a couple other issues not represented in the unittest, for
 example related to template deduction. In a perfect world, Ref would
 masquerade (aside from having a different layout, ctor, and dtor) as an
 lvalue of type T.

 But in fact I think solving the matters above would go a long way toward
 making smart references nicely usable. Although my example is centered
 on reference counting an owner, there are other uses of smart
 references. Are all these worth changing the language?


 Andrei
My modified version: http://dpaste.dzfl.pl/33d4e44c7167 Difference: Added opNewRef to owner which returns a new copy of itself. Minice the current state of the reference counting. I also changed the == in the static asserts that don't work to :. This does work and I argue for alias this, this is correct behavior. Of course this would break wards compatibility a little bit, so maybe a pragma to tell the compiler to include int in ==? pragma(aliasIsThis) struct Ref(T, Owner) { ...
Mar 11 2015
parent "Meta" <jared771 gmail.com> writes:
On Thursday, 12 March 2015 at 04:03:44 UTC, Rikki Cattermole 
wrote:
 Of course this would break wards compatibility a little bit, so 
 maybe a pragma to tell the compiler to include int in ==?

 pragma(aliasIsThis)
 struct Ref(T, Owner) {
     ...
That's not good enough. It'll still fail template constraints.
Mar 11 2015
prev sibling next sibling parent "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Wednesday, 11 March 2015 at 20:33:07 UTC, Andrei Alexandrescu 
wrote:
 #70: Attempting to copy a reference fails on account of the 
 disabled postblit. There should be a way to tell the compiler 
 to automatically invoke alias this and create a copy of that 
 guy.

 #81: Moving from a reference works by moving the Ref object. 
 There should be a way to tell the compiler that moving should 
 really move the payload around.
I suspect this will work automatically if #70 does.
Mar 12 2015
prev sibling parent reply "Zach the Mystic" <reachzach gggmail.com> writes:
On Wednesday, 11 March 2015 at 20:33:07 UTC, Andrei Alexandrescu 
wrote:
 I'm investigating D's ability to define and use smart 
 references. Per the skeleton at 
 http://dpaste.dzfl.pl/9d752b1e9b4e, lines:

 #6: You can't default-initialize a ref.

 #7: You can't copy a ref - copying should mean copying the 
 object itself.

 #9: Per this example I'm hooking a reference with an Owner. The 
 reference hooks calls to opAddRef and opRelease in the owner.

 #23: Assigning the reference really assigns the referred.

 #28: A reference is a subtype of ref T. Most operations against 
 the reference will be automatically forwarded to the underlying 
 object, by reference ("ref" is important here).

 As unittests show, things work quite nicely. There are a few 
 things that don't:

 #70: Attempting to copy a reference fails on account of the 
 disabled postblit. There should be a way to tell the compiler 
 to automatically invoke alias this and create a copy of that 
 guy.

 #81: Moving from a reference works by moving the Ref object. 
 There should be a way to tell the compiler that moving should 
 really move the payload around.

 There are a couple other issues not represented in the 
 unittest, for example related to template deduction. In a 
 perfect world, Ref would masquerade (aside from having a 
 different layout, ctor, and dtor) as an lvalue of type T.

 But in fact I think solving the matters above would go a long 
 way toward making smart references nicely usable. Although my 
 example is centered on reference counting an owner, there are 
 other uses of smart references. Are all these worth changing 
 the language?
Are the suggested changes also related to the possibility of making `ref` a type? I have no opposition in principle to expanding struct semantics to be as transparent as possible. But then I ask, what prevented them from being expanded until now? From reading these forums, I've learned that C++ reference types have a lot of problems. Does expanding the semantics of structs run the risk of encountering same sorts of problems C++ references have? The ideal is to find a way to add semantics without adding ambiguity (i.e. to make sure both the compiler and the programmer always choose the right interpretation of a given construct). So, for example, if you pass a `Ref!X` type to a type `X` parameter, or you pass an `X` type to a `Ref!X` parameter, the result is easy for both the compiler and the human to figure out. That's all I've got.
Mar 13 2015
parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Friday, 13 March 2015 at 15:21:42 UTC, Zach the Mystic wrote:
 On Wednesday, 11 March 2015 at 20:33:07 UTC, Andrei 
 Alexandrescu wrote:
 I'm investigating D's ability to define and use smart 
 references. Per the skeleton at 
 http://dpaste.dzfl.pl/9d752b1e9b4e, lines:

 #6: You can't default-initialize a ref.

 #7: You can't copy a ref - copying should mean copying the 
 object itself.

 #9: Per this example I'm hooking a reference with an Owner. 
 The reference hooks calls to opAddRef and opRelease in the 
 owner.

 #23: Assigning the reference really assigns the referred.

 #28: A reference is a subtype of ref T. Most operations 
 against the reference will be automatically forwarded to the 
 underlying object, by reference ("ref" is important here).

 As unittests show, things work quite nicely. There are a few 
 things that don't:

 #70: Attempting to copy a reference fails on account of the 
 disabled postblit. There should be a way to tell the compiler 
 to automatically invoke alias this and create a copy of that 
 guy.

 #81: Moving from a reference works by moving the Ref object. 
 There should be a way to tell the compiler that moving should 
 really move the payload around.

 There are a couple other issues not represented in the 
 unittest, for example related to template deduction. In a 
 perfect world, Ref would masquerade (aside from having a 
 different layout, ctor, and dtor) as an lvalue of type T.

 But in fact I think solving the matters above would go a long 
 way toward making smart references nicely usable. Although my 
 example is centered on reference counting an owner, there are 
 other uses of smart references. Are all these worth changing 
 the language?
Are the suggested changes also related to the possibility of making `ref` a type?
Are there plans to do this? I remember Walter suggested `ref` for non-parameters, i.e. local variables, but as a storage class, not a type modifier.
Mar 14 2015
parent "Zach the Mystic" <reachzach gggmail.com> writes:
On Saturday, 14 March 2015 at 15:55:51 UTC, Marc Sch├╝tz wrote:
 Are the suggested changes also related to the possibility of 
 making `ref` a type?
Are there plans to do this? I remember Walter suggested `ref` for non-parameters, i.e. local variables, but as a storage class, not a type modifier.
I don't think there are plans per se, but if struct semantics are made powerful and flexible enough, I can imagine it being possible to simply recreate 'ref' parameters as 'Ref!' struct templates. For me, the question is what new additions would have to be added to structs to enable this. It seems like a good thought exercise, regardless of the final decision.
Mar 15 2015