@Araq: > Please don't repeat my mistake, no need to implement it when you can already > talk about it. ;-)
**I really do like to back up my "talking" with little "mini-experiments" in code to prove and develop the concepts**, but I'll have to think more about how to do it simply, as otherwise it needs compiler help. Meanwhile... I'll just throw the idea out and hopefully it isn't too laughable, as follows: 1. We seem to be agreed that we would prefer not to just implement Yet Another Gar(bage) Collector (YAGarC), as we seem to have an excess of them that can be used in Boehm, GoGC, and now "araqgc", which I'm sure can be made to work. All of them will trade computational overheads, against latency, against throughput, and we've grown to not really like any of them, plus any of them can be chosen for those who truly love GC's. 2. This has nothing to do with allocators, of which any of the Nim native one, malloc, mi-malloc, or some other new invented one can be used as appropriate, they all do the same job in providing heap memory when asked for it and freeing it when desired along with a couple of "tweaks" like resizing and reallocating; they just again provide various trade-offs and the new "mi-malloc" seamingly a very good one. 3. The idea of "hooks" strikes my fancy, and in particular the `newObjHook` that when asked for memory returns a pointer to a free area of the requested size, but is well able to have an "extra" attached structure "head" containing anything we desire and do anything else on the side at the same time such as creating and using pointer structures, tables, etc. 4. I don't particularly like the `transverseObjHook` even when it works as it would only seem to be of use in implementing GC's as in requesting a Mark phase or a Sweep phase. Remember, We don't really want YAGarC! 5. We both really like the current destructor/copy/move semantics, which also is what really helped make the `owned ref` B/D reasonably easy to implement; however, although I still like it and think B/D can be combined with this idea in order to optimize non-shared ownership, this idea (kind of) extends it to efficiently "cloning" ownership. 6. So I propose a new `destroyObjHook` (instead of `transverseObjHook` or as well as) that gets called only for `ref`'s when they go out of scope or at the end of `proc`'s just as destructors get called for "nominal" types. If the compiler can figure out when it time to call `=destroy` on those types (or inject a `=destroy` when there isn't one), it should be able to easily do this just for the `ref` type. But wait for it, this isn't all... 7. If `ref`'s are destroyed at the end of scope or `proc` if they haven't been "sink'ed" away, how do we create clones so we have multiple owners of the data? Answer: we (Oh no, that dreaded word) `deepCopy` them. But wait, `deepCopy` in its final (not the `channels` version, which is terrible) actually wasn't so bad, and this isn't the `deepCopy` where everything gets duplicated; this is the overridable `=deepCopy` that can be applied to `ref T` and is always overridden to just do a ref count! In a way, it means that copying of owned ref's is no longer forbidden, it just becomes the some owned ref with a higher separate (permanent even for production) ref count. 8. Now, the destroy called through the hook only destroys if there is no ref count and otherwise just decrements the ref count, and thus the object will only be destroyed once. 9. Oh no, you say, that sounds a lot like atomic ref counting, and that isn't particularly fast. No problem, I say, as this "cloning" only happens when one needs multiple owners such as across threads, which is (should be) quite "coarse graIned" anyway. For other uses, this can be combined with such ideas as B/D if performance turns out to be a problem for almost no overhead (in production, with that part of the "inner" ref counting turned off). 10. Ah, you say, but what about data cycles. Well, I say, maybe the "hooks" can support cycle detection analysis as some sort of deferred action as part of the "semi GC" role through the hooks, and the proposed options of B/D or "araqsgc" don't really handle that very well yet either. 11. But wouldn't this be hard to implement, I hear the (dev) crowd groan. I reply, it seems that you have implemented most of it already, and this just corrects it. Ugly `deepCopy` (as implemented for `threadpool` can be applied in exactly the same places, just it becomes beautiful as it just makes the data structures (including closures, which no longer have to be prohibited) able to be shared. REALLY REALLY UGLY `deepCopy` as implemented in `channels` gets changed to the same `system.deepCopy` (or `system.clone` if you prefer). 12. `async` becomes possible and beautiful and all is sweetness and light. **There, I 'm done talking except for discussion. Does it merit consideration, investigation, and testing?**
