3 ms·
> GCs should be an opt-in niche tool used to solve specific problems. That is true. Sciter (https://sciter.com https://sciter.com) contains implementation of D
by c-smile 7y ago
> GCs should be an opt-in niche tool used to solve specific problems.
That is true. Sciter (https://sciter.com https://sciter.com) contains implementation of DOM(tree), CSS and script.
DOM is a regular tree structure - each element of the tree has strictly one parent and no cycles on the tree in principle. It does not need GC at all and is not using it for DOM tree management.
CSS is a collection of collections of name/value pairs. No loops. It does not need GC at all.
And only script uses GC for the simple reason: in UI, ownership graph of script objects frequently contains loops. Yet lifespan of objects is unknown at compile time - depends on user interactions.
Even purely native GUI application benefits from GC when that GC is used in places where it is needed. GC is just one way (of many) of doing memory management.
Ideally it should be a multi-paradigm programming language and environment that allows to use as explicit memory management (and so RAII, memory pools, etc) as a GC.
int *ptr = …;
gcable int* gptr = …;
But unfortunately such dualism is hard to achieve.
- kazinator 7y agoRather, GC should be default, and you opt-out of GC for specific optimization problems.
- skrimp 7y agoThis is very hard to achieve because GC + RAII do not play nice together. It's hard to reason about whether an RAII resource has been cleaned up since managed objects have non-deterministic destruction. This non-determinism is unsuitable for common RAII patterns like scoped mutex locks. Now, the question being begged is "Can this be avoided by not using destructors with managed objects?" Yes, but not reasonably. Any unmanaged objects that are owned in the entire managed object graph now also have non-deterministic destruction. Thus, the only way to reasonably follow this constraint is to have the compiler disallow/warn when an object with a non-trivial destructor (explicit or implicit) is used with GC. If that wasn't enough of a pain, any runtime-polymorphic types may also need to be destructed and these can't be known at compile time if dynamic linking is used. In essence, these concepts are incompatible to a point where any language supporting both will likely make extensive trade-offs. I find this really sad because many developers may never be exposed to how elegant RAII can be if they are never exposed to non-memory-managed languages. Sure it can be approximated using `with` constructs, but those don't allow resource allocations to cross scope boundaries.