Am 14.04.2013 19:07, schrieb Robert:
>> Does it mean you disagree with proposed compiler changes and with the
>> idea we have to create weak reference functionality instead of
>> recreating it every time it is needed (beside of theoretical danger such
>> approach already showed it as a bad thing with `std.stdio.File` as I wrote)?
>>
>
>
> A weak reference could actually be implemented in the library relatively
> easy. ( I basically did it for std.signals2 )
My memories tell me that I was never able to make a _thread safe_ weak
reference, though. I don't remember exactly, but I think that it was
because the dispose event happens after all threads have already
restarted. This means that some thread could extract a strong reference
from the weak reference before the weak reference knows that the
underlying object has been destroyed, thus creating a dangling pointer.

> My memories tell me that I was never able to make a _thread safe_ weak
> reference, though. I don't remember exactly, but I think that it was
> because the dispose event happens after all threads have already
> restarted. This means that some thread could extract a strong reference
> from the weak reference before the weak reference knows that the
> underlying object has been destroyed, thus creating a dangling pointer.
>
You are right, it is not thread safe. Some hook would be needed that
gets called before threads are resumed. It is not an issue for
std.signals2 because it is not meant to be thread safe.
Best regards,
Robert

> Yes, this is how array of weak references will work because this is how
> weak references work. And this shows one mustn't implement general
> facilities in every case they are needed as he will do mistakes and will
> complicate thinks for himself.
>
If an array of weak references works this way, then it is also easily
implementable in the library. For thread safe weak references another
hook would be necessary though, as Soenke has pointed out.
My current approach is to use a /simplified/*) lock-free list.
Simplified because I make use of the way the GC works, so it is not
thread safe in general. The lazy approach would make this unnecessary.
Maybe I go for lazy, the more sophisticated solution can be implemented
later on if really deemed necessary.
*) It is still brain-fuck though.

> 2. Make regular D objects on closures [4] to be able to know when
> delegate's outer scope is destroyed (this will auto-fix both [5] and
> [2], see Comment 2 of [2] for code example)
I still don't understand what that buys us. Having a closure being an
object would make it possible to use a weak reference, but why would you
want that? The signal would be the only one to hold a reference to the
lamdas context, if this reference was a weak one, then the memory would
be claimed immediately. This is why std.signals2 holds a strong ref to
the delegate context of a wrapping closure and a weak ref to the target
object.

15.04.2013 13:07, Robert пишет:
>> 2. Make regular D objects on closures [4] to be able to know when
>> delegate's outer scope is destroyed (this will auto-fix both [5] and
>> [2], see Comment 2 of [2] for code example)
>
> I still don't understand what that buys us. Having a closure being an
> object would make it possible to use a weak reference, but why would you
> want that? The signal would be the only one to hold a reference to the
> lamdas context, if this reference was a weak one, then the memory would
> be claimed immediately. This is why std.signals2 holds a strong ref to
> the delegate context of a wrapping closure and a weak ref to the target
> object.
With your `std.signals2` one can't e.g. forward delegate connection like
this:
---
/// Usage: don't pass struct pointer delegates as `del`.
void f(void delegate() del)
{
obj.event.connect(del);
}
---
as you require explicit passing an object owning a delegate.
But it is completely unnecessary as delegate do know where it was born
from and the fact this information isn't tracked when a closure is
created is a language design issue. One of those fixing which is easy,
will not break any code and will improve things a lot.
--
Денис В. Шеломовский
Denis V. Shelomovskij

On Monday, 15 April 2013 at 12:07:19 UTC, Denis Shelomovskij
wrote:
> 15.04.2013 13:07, Robert пишет:
>>> 2. Make regular D objects on closures [4] to be able to know
>>> when
>>> delegate's outer scope is destroyed (this will auto-fix both
>>> [5] and
>>> [2], see Comment 2 of [2] for code example)
>>
>> I still don't understand what that buys us. Having a closure
>> being an
>> object would make it possible to use a weak reference, but why
>> would you
>> want that? The signal would be the only one to hold a
>> reference to the
>> lamdas context, if this reference was a weak one, then the
>> memory would
>> be claimed immediately. This is why std.signals2 holds a
>> strong ref to
>> the delegate context of a wrapping closure and a weak ref to
>> the target
>> object.
>
> With your `std.signals2` one can't e.g. forward delegate
> connection like this:
> ---
> /// Usage: don't pass struct pointer delegates as `del`.
> void f(void delegate() del)
> {
> obj.event.connect(del);
> }
> ---
> as you require explicit passing an object owning a delegate.
>
> But it is completely unnecessary as delegate do know where it
> was born from and the fact this information isn't tracked when
> a closure is created is a language design issue. One of those
> fixing which is easy, will not break any code and will improve
> things a lot.
Even with that explanation, I still don't see the problem.

15.04.2013 20:15, deadalnix пишет:
> On Monday, 15 April 2013 at 12:07:19 UTC, Denis Shelomovskij wrote:
>> 15.04.2013 13:07, Robert пишет:
>>>> 2. Make regular D objects on closures [4] to be able to know when
>>>> delegate's outer scope is destroyed (this will auto-fix both [5] and
>>>> [2], see Comment 2 of [2] for code example)
>>>
>>> I still don't understand what that buys us. Having a closure being an
>>> object would make it possible to use a weak reference, but why would you
>>> want that? The signal would be the only one to hold a reference to the
>>> lamdas context, if this reference was a weak one, then the memory would
>>> be claimed immediately. This is why std.signals2 holds a strong ref to
>>> the delegate context of a wrapping closure and a weak ref to the target
>>> object.
>>
>> With your `std.signals2` one can't e.g. forward delegate connection
>> like this:
>> ---
>> /// Usage: don't pass struct pointer delegates as `del`.
>> void f(void delegate() del)
>> {
>> obj.event.connect(del);
>> }
>> ---
>> as you require explicit passing an object owning a delegate.
>>
>> But it is completely unnecessary as delegate do know where it was born
>> from and the fact this information isn't tracked when a closure is
>> created is a language design issue. One of those fixing which is easy,
>> will not break any code and will improve things a lot.
>
> Even with that explanation, I still don't see the problem.
Do you mean that tracking an object with a delegate whenever it goes to
just know where it's outer scope is destroyed is not a problem?
--
Денис В. Шеломовский
Denis V. Shelomovskij

On Tuesday, 16 April 2013 at 05:39:32 UTC, Denis Shelomovskij
wrote:
> Do you mean that tracking an object with a delegate whenever it
> goes to just know where it's outer scope is destroyed is not a
> problem?
Delegate context is allocated on the heap, unless compiler can
prove it can do it on stack. context is destroyed when no live
pointer point to it.
You still didn't explain why an object is better than the actual
delegate mecanism.

16.04.2013 10:10, deadalnix пишет:
> On Tuesday, 16 April 2013 at 05:39:32 UTC, Denis Shelomovskij wrote:
>> Do you mean that tracking an object with a delegate whenever it goes
>> to just know where it's outer scope is destroyed is not a problem?
>
> Delegate context is allocated on the heap, unless compiler can prove it
> can do it on stack. context is destroyed when no live pointer point to it.
>
> You still didn't explain why an object is better than the actual
> delegate mecanism.
Sorry, I really don't understand what you don't understand.
Let's consider example from Issue 9603 Comment 2 [1]. Do you think such
code must not work?
Also you can look through Issue 9601 discussion.
[1] http://d.puremagic.com/issues/show_bug.cgi?id=9603#c2
[2] http://d.puremagic.com/issues/show_bug.cgi?id=9601--
Денис В. Шеломовский
Denis V. Shelomovskij

On Tuesday, 16 April 2013 at 07:55:51 UTC, Denis Shelomovskij
wrote:
> Sorry, I really don't understand what you don't understand.
>
> Let's consider example from Issue 9603 Comment 2 [1]. Do you
> think such code must not work?
>
> Also you can look through Issue 9601 discussion.
>
> [1] http://d.puremagic.com/issues/show_bug.cgi?id=9603#c2
> [2] http://d.puremagic.com/issues/show_bug.cgi?id=9601
The code in 9603 is completely broken. It should compile and run,
but what it does is undefined as o is finalized when delegates
have reference to it.
I don't see how changing delegate into object would change
anything, as the code would be broken in the same way for the
same reason.