Iām with you that itād be nice to not need any type of GC background process, but aside from Rustās model I just canāt think of a way to do that. This was the best I could do at minimizing it, and working with Unity where you have to actively avoid the GC, at least this way it doesnāt get in the way of doing real-time work. To actually get away from it, youād need to either do some self-management of pools or not allow tasks to create new ones, and then you have to be really careful to not run out of memory.
As far as your concern about leaking being bad, I agree that itād probably put some people off, although I donāt think thatās necessarily rational - real GC languages do that too, itās just you have more of a guarantee that memory will be available when you need it. I think the biggest issue here is youād have to be really aware of how much memory youāre going to need for each task, otherwise you could easily run out if you have a few concurrent tasks that take more than you expected. Youād have to make sure that if your usage was unbounded you use a real allocator and RAII. It also would make allocation really tedious, because you have to either handle the error case everywhere (imagine if Box::new returned an Option in Rust) or accept that tasks crash like Erlang, which needs a runtime. I donāt really like either of those.
Iām thinking though, it might work to not encourage leaking but just say donāt worry about it too much? So youād use RAII objects, but in the case where you have cycles or shared references, you just forget about it and theyāll be reclaimed when the task finishes. I think you could even get by without a runtime if you have language support for tasks as regions and donāt build in green threads like Go. The pool manager would post notifications about memory usage to a user defined callback, which you could either handle yourself or use the default background thread handler.
Not sure how threading would work yet, since that would not be a subset of the parent task unless you had something like rayon::Scope. I guess youād need some type of move/copy semantics between regions, and probably refcounted pointers.
Hmm, FFI is gonna be tricky. I guess youāre kind of on your own there. I think maybe to make it safer youād restrict it to memory thatās not part of an auto-freed pool, although I think it should be up to the user to decide whether that particular call holds on to the memory or not.
I think if I go too much further Iām just going to end up confusing myself, but go ahead and nitpick, I need it if Iām gonna have any chance of making this work.