March 03, 2015
On 3/3/15 12:53 AM, Volodymyr wrote:
> On Thursday, 26 February 2015 at 21:50:56 UTC, Andrei Alexandrescu wrote:
>> http://wiki.dlang.org/DIP74 got to reviewable form. Please destroy and
>> discuss.
>>
>> Thanks,
>>
>> Andrei
>
> With opAddRef/opRelease class does respondible for its dealocation and
> its own payload so breaks SOLID's single responsibility principle.

Correct. That's a tactical matter that can be addressed e.g. with mixin templates.

> As
> for me better design will be to do it closer to C++'s shared_ptr.
> e.g:
>
> // maybe with @arc
> struct RefCounter(T)
> {
> void opAddRef();
> void opRelease();
> ref T obj;
> ref size_t count;
> }
> }
>
> RefCounter!Widged myRefToWidget;
>
> RefCounter with default ctor/dtor. opAddRef and opRelease is for
> compiler optimtimisation and elimination of redunadant ref counter
> increment/decrement.

We couldn't make that work with safety.


Andrei

March 04, 2015
On Tuesday, 3 March 2015 at 09:58:12 UTC, Andrei Alexandrescu wrote:
> On 3/3/15 12:53 AM, Volodymyr wrote:
>> On Thursday, 26 February 2015 at 21:50:56 UTC, Andrei Alexandrescu wrote:
>>> http://wiki.dlang.org/DIP74 got to reviewable form. Please destroy and
>>> discuss.
>>>
>>> Thanks,
>>>
>>> Andrei
>>
>> With opAddRef/opRelease class does respondible for its dealocation and
>> its own payload so breaks SOLID's single responsibility principle.
>
> Correct. That's a tactical matter that can be addressed e.g. with mixin templates.
>
>> As
>> for me better design will be to do it closer to C++'s shared_ptr.
>> e.g:
>>
>> // maybe with @arc
>> struct RefCounter(T)
>> {
>> void opAddRef();
>> void opRelease();
>> ref T obj;
>> ref size_t count;
>> }
>> }
>>
>> RefCounter!Widged myRefToWidget;
>>
>> RefCounter with default ctor/dtor. opAddRef and opRelease is for
>> compiler optimtimisation and elimination of redunadant ref counter
>> increment/decrement.
>
> We couldn't make that work with safety.
>
>
> Andrei

Why couldn't? Let's for all @return (this) functions make wrappers that rerturn RefCounter!MemberType(member, ownerCounterPtr), and same thing for public fields

The wrapper nedded only for realy owned resources (but not simple gc's refs).
March 04, 2015
Implicit conversion to supertypes (class or interface) is allowed
ONLY if the supertype is also a reference counted type. It
follows that reference counted types cannot be converted to
Object (unless Object itself defines the two methods).

But how about calling methods of supertypes?

class Basic
{
Basic castToBasic() return
{
     return this;
}

}

class RCWidged : Basic
{
void opAddRef();
void opRelease();
// etc
}

Object a;
{
auto b = RCWidget;
a = b.castToBasic; // unsafe? opAddReff?
// b.opRelease?
}

a < new RCWidget // call to Object.opCmp. Error?

The problem with shared_ptr-like solution - "this" parameter is
not shared_ptr. You try to build shared_ptr into "this". But
basic class knows nothing about RC in child class. And those who
use the basic class know nothing.

RefCounter is unsafe and mutable. Let's do it universal (for
classes/value structs/ and unions), add method
auto opShareResource(T)(ref T t)
to handle parts of RC class that go away.

auto opShareResource(T)(ref T t)
{
     return RefCounter!T(t, ownerRefCounter);
}

this method will be called for direct or indirect access to
fields of RCClass and may wrap resource or throw or do anything
else.
March 04, 2015
On 3/4/15 5:08 AM, Volodymyr wrote:
> Implicit conversion to supertypes (class or interface) is allowed
> ONLY if the supertype is also a reference counted type. It
> follows that reference counted types cannot be converted to
> Object (unless Object itself defines the two methods).
>
> But how about calling methods of supertypes?

That also entails an implicit conversion. To clarify, I added this to http://wiki.dlang.org/DIP74#General:

"Method calls to supertypes are only allowed if the supertype that defines the method is also reference counted."


Andrei
March 04, 2015
After looking at DIP74, it seems that there is no way to create a weak reference to a ref counted object, but is not explicitly stated. Has this idea been considered at all?

March 04, 2015
On 3/4/15 10:48 AM, bitwise wrote:
> After looking at DIP74, it seems that there is no way to create a weak
> reference to a ref counted object, but is not explicitly stated. Has
> this idea been considered at all?

DIP74 aims at not disallowing weak references whilst leaving it to libraries to effect implementations, but we'd need a proof of concept implementation to make sure DIP74 is enough as is. -- Andrei

March 04, 2015
On Wednesday, 4 March 2015 at 18:59:54 UTC, Andrei Alexandrescu wrote:
> On 3/4/15 10:48 AM, bitwise wrote:
>> After looking at DIP74, it seems that there is no way to create a weak
>> reference to a ref counted object, but is not explicitly stated. Has
>> this idea been considered at all?
>
> DIP74 aims at not disallowing weak references whilst leaving it to libraries to effect implementations, but we'd need a proof of concept implementation to make sure DIP74 is enough as is. -- Andrei

I suppose you could add "getWeak()" and "releaseWeak()" to a ref counted class, and implement a "struct Weak(T)" that calls them for you, but I doesn't seem like much of a leap to just add something like this to the DIP.

couldn't "opAddWeak" and "opReleaseWeak" be added and follow identical rules to "opAddRef" and "opRelease"? The compiler could simply insert "opAddWeak() instead of opAddRef() when it found the "weak" keyword.

For example:

class Widget {
    private uint _refs = 1;
    private uint _weaks = 0;

    private int[] _payload; // owned
 	
    void opAddRef() {
        ++_refs;
    }
    void opRelease() {
        if (--_refs == 0) {
            GC.free(_payload.ptr);
            _payload = null;

            // I'm assuming this would leave "_weaks" and "_refs" untouched
            this.destroy();

            if(_weaks == 0) {
            	GC.free(cast(void*)this);
            }
        }
    }

    void opAddWeak() {
    	++_weaks;
    }
    void opReleaseWeak() {
    	if(--_weaks == 0 && _refs == 0) {
		GC.free(cast(void*)this);
        }
    }

    // optional/recommended
    bool expired() {
		return _refs == 0;
    }
}

Widget a = new Widget; // refs == 1, weaks == 0

Widget b = weak a; // refs == 1, weaks == 1
//a.opAddWeak();

Widget c = b;
// b.opAddRef(); // refs == 2, weaks == 1

a = null; // refs == 1, weaks == 1
//a.opRelease();

assert(b.expired() == false);

c = null; // refs == 0, weaks == 1
// c.opRelease();

assert(b.expired() == true);

b = null; // refs == 0, weaks == 0
// b.opReleaseWeak();

////////// or for function calls:

void func(weak Widget a) {
	//...
}

Widget a = new Widget;
func(a);
March 04, 2015
On 3/4/15 12:04 PM, bitwise wrote:
> I suppose you could add "getWeak()" and "releaseWeak()" to a ref counted
> class

My initial attempt would be to see if opAddRef and opRelease defined by a distinct weak pointer type would work. -- Andrei
2 3 4 5 6 7 8 9 10 11 12
Next ›   Last »