April 16, 2013
Am Sun, 14 Apr 2013 21:29:07 +0200
schrieb Robert <jfanatiker@gmx.at>:

> 
> > IMHO if a object still is connected to a active signal it should not be collected. So the place where the signal stores the handler should be scanned by the GC as usual. Then just document clearly that you have to remove a handler to make sure that garbage collection can really kick in.
> 
> If you really want this behaviour, all you need is an array of delegates. But in my experience you don't usually want that, because you would have to take care of dropping any connections by hand, which is even more cumbersome than manual memory management in some regards.
> 
> Best regards,
> Robert
> 

But what if my only reference to the handler is in the signal and I don't want it to get disconnected / cleaned up?

struct FileLogger
{
    File f;
    void onSomething()
    {
        f.writeln("Something happened");
    }
}

a.onSomething ~= &(new FileLogger()).onSomething;
(The FileLogger should only get destroyed if a is destroyed)

I have used that concept quite often in C#. Of course it's also dangerous as it could cause memory leaks if used wrong. But I think we should at least have the option of doing things like these. (Allowong both strong & weak references as suggested by Kapps seems to be a good solution)
April 16, 2013
> (Allowong
> both strong & weak references as suggested by Kapps seems to be a good
> solution)

std.signals2 supports both, just use strongConnect().

Best regards,
Robert

April 17, 2013
16.04.2013 13:17, deadalnix пишет:
> 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.

Current behaviour when delegates stays alive when its outer scope is destroyed is just a bad language design.

Let's assume there is a "magic" way to make code in Issue 9603 work. Do you think this is usable?

So, the "magic": I propose to make an object on closure creation (i.e. just prepend allocated closure with few hidden fields) and add "finalize the closure" to outer scope dispose event. And I already described it in Issue 9601 and its comments. What is non-obvious here?

Note: This can work just the same way if there is no GC-allocated closure.

-- 
Денис В. Шеломовский
Denis V. Shelomovskij
April 17, 2013
On Wednesday, 17 April 2013 at 06:15:43 UTC, Denis Shelomovskij wrote:
> Current behaviour when delegates stays alive when its outer scope is destroyed is just a bad language design.
>

No, destroying is unsafe by definition, and this is why GC solve a lot of problems.

Can you explain what is the problem ? What does creating an object change except adding 2 pointers into the frame pointer ?
April 17, 2013
17.04.2013 10:43, deadalnix пишет:
> On Wednesday, 17 April 2013 at 06:15:43 UTC, Denis Shelomovskij wrote:
>> Current behaviour when delegates stays alive when its outer scope is
>> destroyed is just a bad language design.
>>
>
> No, destroying is unsafe by definition, and this is why GC solve a lot
> of problems.

I mead destroying by GC.

> Can you explain what is the problem ?

Code in Issue 9603 doesn't work.

> What does creating an object change except adding 2 pointers into the frame pointer ?

It will make code in Issue 9603 work.

-- 
Денис В. Шеломовский
Denis V. Shelomovskij
April 17, 2013
On 04/17/2013 12:35 PM, Denis Shelomovskij wrote:
> ...
>
> It will make code in Issue 9603 work.
>

You have to argue why this is the correct way to fix it. Why would lifetime control necessarily be linked to implicit object field overhead?
April 17, 2013
On Wednesday, 17 April 2013 at 10:35:08 UTC, Denis Shelomovskij wrote:
>> Can you explain what is the problem ?
>
> Code in Issue 9603 doesn't work.
>

That is not explaining what is the problem. This should contains at least :
 - Why it doesn't work.
 - What is the fundamental problem.
 - Why this fundamental problem is a language issue and not a lib one.
 - How does you proposition solve it.

Right now, the only element you have been able to provide are :
 - signal accept delegate from object.
 - So we must make all delegate object.

This is a very poor argumentation as the only reasonable answer to 1 without more input is go fix signal or raise a bug about signal.
April 18, 2013
17.04.2013 15:26, Timon Gehr пишет:
> On 04/17/2013 12:35 PM, Denis Shelomovskij wrote:
>> ...
>>
>> It will make code in Issue 9603 work.
>>
>
> You have to argue why this is the correct way to fix it. Why would
> lifetime control necessarily be linked to implicit object field overhead?

0. I do like this approach, it looks straight and consistent IMO.
1. I see no other ways to fix the issue.
2. I see no important overhead in my proposal as wasting a few bytes is nothing in contrast with GC allocation process/memory overhead.
3. I think added functionality is very usable and even already required.

Everyone is free to propose a better approach.

By the way, almost every technical idea we know is incorrect and will be likely superceeded in the future with a better one as history shows.

-- 
Денис В. Шеломовский
Denis V. Shelomovskij
April 18, 2013
17.04.2013 19:47, deadalnix пишет:
> On Wednesday, 17 April 2013 at 10:35:08 UTC, Denis Shelomovskij wrote:
>>> Can you explain what is the problem ?
>>
>> Code in Issue 9603 doesn't work.
>>
>
> That is not explaining what is the problem. This should contains at least :
>   - Why it doesn't work.

No ability to tell when a delegate will be destroyed (currently it isn't even destroyed when it should, see Issue 9602).
http://d.puremagic.com/issues/show_bug.cgi?id=9602

>   - What is the fundamental problem.

When a delegate is created information about it's outer scope is lost instead of being stored in it's ptr.

>   - Why this fundamental problem is a language issue and not a lib one.

Looks self-evident.

>   - How does you proposition solve it.

It stores the information about delegate's outer scope wasting (oh God, how many, especially in contrast to GC allocation) a few bytes.

>
> Right now, the only element you have been able to provide are :
>   - signal accept delegate from object.
>   - So we must make all delegate object.
>
> This is a very poor argumentation as the only reasonable answer to 1
> without more input is go fix signal or raise a bug about signal.

As everything I have written above is known, I still don't understand why you are telling about signal fixing as a main problem as it is just an example of problems that occurs when we throw away outer scope information without any practical reason, IMO.

-- 
Денис В. Шеломовский
Denis V. Shelomovskij
April 18, 2013
On Thursday, 18 April 2013 at 13:25:32 UTC, Denis Shelomovskij wrote:
>>  - What is the fundamental problem.
>
> When a delegate is created information about it's outer scope is lost instead of being stored in it's ptr.
>

That doesn't mean anything. No information is stored into a ptr except an address in memory.

>>  - Why this fundamental problem is a language issue and not a lib one.
>
> Looks self-evident.
>

It look self evident to me that the earth is flat when I look through the window.

>>  - How does you proposition solve it.
>
> It stores the information about delegate's outer scope wasting (oh God, how many, especially in contrast to GC allocation) a few bytes.
>

I don't care about the cost. You have made no point in 3 pages in favor of the change you propose. Not even an invalid point I can disagree on.

> As everything I have written above is known, I still don't understand why you are telling about signal fixing as a main problem as it is just an example of problems that occurs when we throw away outer scope information without any practical reason, IMO.

It is an example of a library interface issue (very real). To propose a language change, you must show that this limitation is in fact a symptom of a deeper cause, which it at language level (so that must be fixed at language level).