Thread overview
DIP74 & GC Destructors
Jun 15, 2015
rsw0x
Jun 15, 2015
Marc Schütz
Jun 16, 2015
rsw0x
Jun 16, 2015
Marc Schütz
June 15, 2015
Andrei mentioned work on reference counting recently so I'm assuming there's still plans on implementing DIP74¹.

With reference counted objects built into the language, it might be worth investigating dropping destructors from all non-RC'd GC allocated objects for a complete separation of objects that control resources and need finalization, and objects that do not.

The current destructor implementation is incredibly bug prone, and is often almost always misused. It has already been made quite clear that you _can not_ rely on the GC for releasing resources². The current GC is even non-reentrant³, meaning that you can't allocate in destructors. You also have to assume any other reference to heap-allocated memory is in an undefined state during a destructor, further limiting their usefulness.

Furthermore, not having to worry at all about destructors would improve the performance of the GC. The GC could just mark large blocks of memory as free without having to scan which blocks of memory have destructors, which can slow down sweeping(I have yet to do any sort of testing on this, it is just a theory.)

One of the main concerns when choosing D as a language is the GC performance, I think this is a well accepted fact. It's worth evaluating anything that might improve the performance of the GC in my opinion.

Bye.

¹ - http://wiki.dlang.org/DIP74
² - http://dlang.org/class.html#Destructor "... The garbage collector is not guaranteed to run the destructor for all unreferenced objects"
³ - http://dlang.org/phobos/core_exception.html#.InvalidMemoryOperationError
June 15, 2015
I hope we won't get builtin RC, but that's off-topic.

In any case, there has been talk about introducing finalizers instead of destructors for GC managed objects. rt_attachDisposeEvent() already exists and is used by std.signal for weak references, but it's a hack, it needs to be formalized.

These finalizers can then have much more restricted semantics than destructors, e.g. they must be callable on any thread, are generally un-@safe if they access members with indirections, and so on.
June 16, 2015
On Monday, 15 June 2015 at 16:20:56 UTC, Marc Schütz wrote:
> I hope we won't get builtin RC, but that's off-topic.

I disagree, that's entirely on topic. I believe every modern implementation of Ada relies solely on RC(while having GC hooks.) Nobody really seems to have an issue with RC there. I personally believe that immediate RC and GC solve completely different issues of deterministic vs non-deterministic resource management. Trying to shoehorn them into the same thing gets you a broken, slow implementation(see: C++'s shared_ptr. It's dog slow and _way_ overused IMO.)

>
> In any case, there has been talk about introducing finalizers instead of destructors for GC managed objects. rt_attachDisposeEvent() already exists and is used by std.signal for weak references, but it's a hack, it needs to be formalized.
>
> These finalizers can then have much more restricted semantics than destructors, e.g. they must be callable on any thread, are generally un-@safe if they access members with indirections, and so on.

I'm honestly curious of examples where finalizers are needed. The one exception I can think of is managing non-GC objects, as in C#. But that *still* seems like a bad idea because there's zero guarantee the destructor will ever run - i.e, a GC implementation that decides to just never call destructors is a valid implementation.

http://dlang.org/class.html#destructors
"The garbage collector is not guaranteed to run the destructor for all unreferenced objects. "

D has more than one issue here, from combining "finalizer" and "destructor" into the same term to destructors being incredibly bug-prone and almost useless as defined by the standard.

I hope this gets looked at.

Bye.
June 16, 2015
On Tuesday, 16 June 2015 at 15:48:18 UTC, rsw0x wrote:
> On Monday, 15 June 2015 at 16:20:56 UTC, Marc Schütz wrote:
>> I hope we won't get builtin RC, but that's off-topic.
>
> I disagree, that's entirely on topic. I believe every modern implementation of Ada relies solely on RC(while having GC hooks.) Nobody really seems to have an issue with RC there. I personally believe that immediate RC and GC solve completely different issues of deterministic vs non-deterministic resource management. Trying to shoehorn them into the same thing gets you a broken, slow implementation(see: C++'s shared_ptr. It's dog slow and _way_ overused IMO.)

Note that I'm all for supporting good RC, I'm just against adding special support for it _in the language_. Instead, the remaining obstacles for efficient and safe library-based RC should be solved, which from my POV mostly means implementing some version of the `scope` feature.

>> In any case, there has been talk about introducing finalizers instead of destructors for GC managed objects. rt_attachDisposeEvent() already exists and is used by std.signal for weak references, but it's a hack, it needs to be formalized.
>>
>> These finalizers can then have much more restricted semantics than destructors, e.g. they must be callable on any thread, are generally un-@safe if they access members with indirections, and so on.
>
> I'm honestly curious of examples where finalizers are needed.

Well, as I already mentioned, weak references, e.g. for a signal/slot mechanism, or for maintaining a cache that doesn't keep its contents alive. Apart from that, I don't see much use in them either. OTOH, weak references _are_ important, so there needs to be some mechanisms for implementing them. I guess finalizers are the easiest way to do it.

> The one exception I can think of is managing non-GC objects, as in C#. But that *still* seems like a bad idea because there's zero guarantee the destructor will ever run - i.e, a GC implementation that decides to just never call destructors is a valid implementation.

Agreed.

>
> http://dlang.org/class.html#destructors
> "The garbage collector is not guaranteed to run the destructor for all unreferenced objects. "
>
> D has more than one issue here, from combining "finalizer" and "destructor" into the same term to destructors being incredibly bug-prone and almost useless as defined by the standard.
>
> I hope this gets looked at.

Agreed, too.