March 03, 2015
On Tuesday, 3 March 2015 at 05:12:15 UTC, Walter Bright wrote:
> On 3/2/2015 6:04 PM, weaselcat wrote:
>> On Tuesday, 3 March 2015 at 01:56:09 UTC, Walter Bright wrote:
>>> On 3/2/2015 4:40 PM, deadalnix wrote:
>>>> After moving resources, the previous owner can no longer be used.
>>>
>>> How does that work with the example presented by Marc?
>>
>> He couldn't pass s and a member of s because s is borrowed as mutable.
>> He would have to pass both as immutable.
>
> A pointer to s could be obtained otherwise and passed.

Under normal circumstances, if the pointer to s is an lvalue, the refcount will be bumped when it is taken.

Isn't the only problem now aliasing something (i.e. a global) invisibly through a parameter? This is easily solved -- when passing a global reference, or duplicating a variable in the same call, wrap the call in an add/release cycle. This preserves the alias for the duration of the call.

Or are we also talking about taking the address of a non-rc'd subcomponent of an rc'd struct?
March 03, 2015
On Monday, 2 March 2015 at 22:58:19 UTC, Walter Bright wrote:
> Pretty dazz idea, dontcha think? And DIP25 still stands unscathed :-)
>
> Unless, of course, we missed something obvious.

I was dazzed, but I'm not anymore. I wrote my concern here:

http://forum.dlang.org/post/ylpaqhnuiczfgfpqjuww@forum.dlang.org
March 03, 2015
On 3/3/15 7:38 AM, Zach the Mystic wrote:
> On Monday, 2 March 2015 at 22:58:19 UTC, Walter Bright wrote:
>> Pretty dazz idea, dontcha think? And DIP25 still stands unscathed :-)
>>
>> Unless, of course, we missed something obvious.
>
> I was dazzed, but I'm not anymore. I wrote my concern here:
>
> http://forum.dlang.org/post/ylpaqhnuiczfgfpqjuww@forum.dlang.org

There's a misunderstanding here. The object being assigned keeps a trailing list of past values and defers their deallocation to destruction. -- Andrei

March 03, 2015
On Tuesday, 3 March 2015 at 16:31:07 UTC, Andrei Alexandrescu wrote:
>> I was dazzed, but I'm not anymore. I wrote my concern here:
>>
>> http://forum.dlang.org/post/ylpaqhnuiczfgfpqjuww@forum.dlang.org
>
> There's a misunderstanding here. The object being assigned keeps a trailing list of past values and defers their deallocation to destruction. -- Andrei

So you need an extra pointer per instance? Isn't that a big price to pay? Is the only problem we're still trying to solve aliasing which is not recognized as such and therefore doesn't bump the refcounter like it should? An extra pointer would be overkill for that. Isn't it better to just recognize the aliasing when it happens?

As far as taking the address of an RcArray element, the type of which element is not itself Rc'ed, it's a different problem. The only thing I've been able to come up with is maybe to create a wrapper type within RcArray for the individual elements, and have that type do refcounting on the parent instead of itself, if that's possible.
March 03, 2015
On Tuesday, 3 March 2015 at 09:05:46 UTC, Walter Bright wrote:
> On 3/2/2015 9:58 PM, weaselcat wrote:
>> Borrowing 'a' from a struct would make the parent struct immutable during the
>> borrow scope of 'a', I believe.
>
> Right, now consider that struct is a leaf in a complex graph of data structures.

Rust has several pointer types, so what is gonna happen depend on the pointer type. However, either the entry in the graph you have owns 'a', in which case it can be disabled as only one owner of a exists, so there is no problem tracking it, or the thing is borrowed, in which case you can have multiple path to 'a' but you cannot borrow yourself (unless it is immutable).
March 03, 2015
On Tuesday, 3 March 2015 at 15:03:41 UTC, Andrei Alexandrescu wrote:
> On 3/3/15 5:45 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:
>> On Tuesday, 3 March 2015 at 09:05:46 UTC, Walter Bright wrote:
>>> On 3/2/2015 9:58 PM, weaselcat wrote:
>>>> Borrowing 'a' from a struct would make the parent struct immutable
>>>> during the
>>>> borrow scope of 'a', I believe.
>>>
>>> Right, now consider that struct is a leaf in a complex graph of data
>>> structures.
>>
>> Then you still cannot have more than one mutable reference to the entire
>> graph. Because that is impractical, Rust uses unsafe (i.e. @trusted in D
>> speak) accessors that "cast away" the ownership, but do so in a way that
>> doesn't violate the guarantees.
>>
>> For example, the type system doesn't allow you to get mutable references
>> to the left and right children of a binary tree node. But there can be
>> an accessor method that internally does some unsafe magic to return a
>> tuple with mutable references to them, annotated with the information
>> that they are mutably borrowed from the node. Both child refs are
>> mutable, and the parent node is inaccessible as long as they exist.
>
> Well... the bigger problem is that it's relying on a convention. The accessor method needs to be constructed in a particular way that's easy to get wrong and that the compiler has no way to check for us.
>
> :o)

To avoid misunderstandings: It is in reply to a sub-thread where Walter asked about how Rust's type system works. This is an example for Rust, not for D.

Therefore, your reply isn't really valid. In Rust, it is an escape hatch from a fundamentally safe type system, whereas in D it would be a necessary convention to make usage of RC safe.
March 03, 2015
On Tuesday, 3 March 2015 at 15:01:02 UTC, Andrei Alexandrescu wrote:
> On 3/3/15 5:05 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:
>> The object is still accessible after its refcount went to zero, and can
>> therefore potentially be resurrected. Probably not a problem, but needs
>> to be taken into account, in particular in with respect to the freelist.
>> That's tricky, because an object can be released and resurrected several
>> times, and care must be taken that it will not end up in the freelist
>> and get destroyed multiple times. And that hasn't even touched on
>> thread-safety yet.
>
> Could you please give an example?

No, I can't, because it isn't true. I was confused...
March 03, 2015
On Tuesday, 3 March 2015 at 17:00:17 UTC, Zach the Mystic wrote:
> On Tuesday, 3 March 2015 at 16:31:07 UTC, Andrei Alexandrescu wrote:
>>> I was dazzed, but I'm not anymore. I wrote my concern here:
>>>
>>> http://forum.dlang.org/post/ylpaqhnuiczfgfpqjuww@forum.dlang.org
>>
>> There's a misunderstanding here. The object being assigned keeps a trailing list of past values and defers their deallocation to destruction. -- Andrei
>
> So you need an extra pointer per instance? Isn't that a big price to pay?

All instances need to carry a pointer to refcount anyway, so the freelist could just be stored next to the refcount. The idea of creating that list, however, is more worrying, because it again involves allocations. It can get arbitrarily long.

> Is the only problem we're still trying to solve aliasing which is not recognized as such and therefore doesn't bump the refcounter like it should? An extra pointer would be overkill for that. Isn't it better to just recognize the aliasing when it happens?
>
> As far as taking the address of an RcArray element, the type of which element is not itself Rc'ed, it's a different problem. The only thing I've been able to come up with is maybe to create a wrapper type within RcArray for the individual elements, and have that type do refcounting on the parent instead of itself, if that's possible.

No, Andrei's proposed solution would take care of that. On assignment to RCArray, if the refcount goes to zero, the old array is put onto the cleanup list. But there can still be borrowed references to it's elements. However, these can never outlive the RCArray, therefore it's safe to destroy all of the arrays in the cleanup list in the destructor.
March 03, 2015
On 3/3/15 9:30 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:
> On Tuesday, 3 March 2015 at 15:01:02 UTC, Andrei Alexandrescu wrote:
>> On 3/3/15 5:05 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>"
>> wrote:
>>> The object is still accessible after its refcount went to zero, and can
>>> therefore potentially be resurrected. Probably not a problem, but needs
>>> to be taken into account, in particular in with respect to the freelist.
>>> That's tricky, because an object can be released and resurrected several
>>> times, and care must be taken that it will not end up in the freelist
>>> and get destroyed multiple times. And that hasn't even touched on
>>> thread-safety yet.
>>
>> Could you please give an example?
>
> No, I can't, because it isn't true. I was confused...

<silently wipes sweat off forehead>
March 03, 2015
On 3/3/15 9:40 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:
> On Tuesday, 3 March 2015 at 17:00:17 UTC, Zach the Mystic wrote:
>> On Tuesday, 3 March 2015 at 16:31:07 UTC, Andrei Alexandrescu wrote:
>>>> I was dazzed, but I'm not anymore. I wrote my concern here:
>>>>
>>>> http://forum.dlang.org/post/ylpaqhnuiczfgfpqjuww@forum.dlang.org
>>>
>>> There's a misunderstanding here. The object being assigned keeps a
>>> trailing list of past values and defers their deallocation to
>>> destruction. -- Andrei
>>
>> So you need an extra pointer per instance? Isn't that a big price to pay?
>
> All instances need to carry a pointer to refcount anyway, so the
> freelist could just be stored next to the refcount. The idea of creating
> that list, however, is more worrying, because it again involves
> allocations. It can get arbitrarily long.

No, the cool thing about freelists is they use free memory to chain things together.

Somebody please write the code already. With no code we sit forever on our testes speculating.

>> Is the only problem we're still trying to solve aliasing which is not
>> recognized as such and therefore doesn't bump the refcounter like it
>> should? An extra pointer would be overkill for that. Isn't it better
>> to just recognize the aliasing when it happens?
>>
>> As far as taking the address of an RcArray element, the type of which
>> element is not itself Rc'ed, it's a different problem. The only thing
>> I've been able to come up with is maybe to create a wrapper type
>> within RcArray for the individual elements, and have that type do
>> refcounting on the parent instead of itself, if that's possible.
>
> No, Andrei's proposed solution would take care of that. On assignment to
> RCArray, if the refcount goes to zero, the old array is put onto the
> cleanup list. But there can still be borrowed references to it's
> elements. However, these can never outlive the RCArray, therefore it's
> safe to destroy all of the arrays in the cleanup list in the destructor.

Yes, that's exactly right, thanks for putting it so clearly.


Andrei