On Saturday, 3 May 2014 at 12:28:03 UTC, monnoroch wrote:
Back to the dtors: i understand, that all the stuff you propose could make GC faster, simpler, and cooler,

Note that this is _not_ the motivation behind the discussed changes. It's primarily about correctness and consistency. What we currently have if something that doesn't work at all in some cases (dynamic arrays, new with structs), and where it does work (class destructors) users have to conform to various rules as to what is allowed in a GC-called destructor (e.g. don't access references to other objects, don't throw (?), don't use thread-local globals, any probably many more subtle rules), that mostly cannot be enforced statically or even at runtime, potentially causing silent corruption if you fail to comply with them. This is IMO more than enough motivation to do something about it.

but it sounds insane to anyone, who uses the language, not develops it, that if you create struct object, dror will be called, but if you place the copy in a container, it wont. It's just unanderstandable from user's point of view.

Not in a container, but making it GC managed. And IMO, it's unreasonable to expect deterministic behaviour from a tracing (non-precise) GC, which is inherently non-deterministic. The real problem is that you can currently do these things accidentally, without noticing it.

1) C.
That is the simplest way: fully-manual resource management.
It's obvious, we can't do that in D, because it's supposed to be simpler for coding, than C.

Again, the main motivation for GC is safety and enabling more idioms that would otherwise be impossible, _not_ lazyness on the part of the programmer.

3) C++.
This one is semi-automatic (talking about user code, not some allocator libraries): you choose the scheme (refcounting, unique reference) and then it'll do the rest.

4) Rust.
I'm not a pro here, but as i understand, it uses C++ way, and adds gc-collected pointers, but not sure, so help me here.

You could describe it like that, yes. But it's a lot more involved. In a way, Rust's owned types are the opposite of a GC: A GC destroys objects lazily and keeps them alive as long as they are referenced. Owned objects are destroyed eagerly at the end of their scope, but the type system ensures that there are no references to them at this point.

What i propose, is to include new concept in D: scoped objects.
Any object (no matter is it a class or struct instance) can be either scoped or not. Dtors for scoped objects are called when out of scope, dtors for non-scoped objects are not called at all.

It is actually as simple as rewrite code

A a = A();

as

A a = A();
scope(exit)
    a.~A();


There is std.typecons.scoped for that, and the deprecated scope classes. Also see deadalnix's `isolated` proposal:

http://forum.dlang.org/thread/yiwcgyfzfbkzcavuq...@forum.dlang.org

But I'm afraid your suggestion is unsafe: There also needs to be a way to guarantee that no references to the scoped object exist when it is destroyed.

I also don't think it's a good idea to have a hard-coded list of types that are scoped. This either needs to be specified by the user of the type (at instantion) and then become part of the type (like const), or it needs to be specified by the implementer of the type, as a requirement that it can only be instantiated as a scoped type, or as garbage-collected or reference-counted or ...

Reply via email to