@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?**

Reply via email to