I'm also a bit surprised there isn't more of a transition to modern C++ for problems where so much time is spent fighting the garbage collection. Ownership and memory management in C++11 and up really isn't a big deal. Keep your allocations to a minimum, make sure you are moving instead of copying. Shared pointers are there, but I actually never use them.
At least in Java land, within in the few years GC will be something you don't have to think about unless you need sub ms promise
But regardless, you could use the Boehm GC for objects you don’t feel like tracking the lifetime of.
Albeit most of that is moot when compared to a GCed language like the global discussion.
Imagine store instructions that can tell memory some metadata about what's stored. "This is a pointer in an object at offset O to another object". "This is an object with a header you can use to paint objects". "This is no longer an object or a pointer". Also imagine instructions like "clear all object paint", "do a one layer trace", and "report unreachable objects". The one-layer trace would have every cell that has a pointer paint the pointed to object with either a "reachable by a reachable object" or "reachable by an object whose reachable state is unknown".
Then GC could proceed as follows: clear all object painting, use the CPU to scan roots to the first objects on the heap and mark those reachable, do two runs of one-layer traces, report unreachable objects and reclaim them.
Something like that.
Most of the minicomputers they we're competing with were more or less true von Neumann architectures without caches. That meant that one those systems the I fetch of the interpreter itself was constantly competing for memory bandwidth with the actual Lisp code it's interpreting and it's data. By pushing the interpreter into microcode, you've created a Harvard arch where the interpreter can fetch out of uCode entirely and not pollute the main system bus. IMO this is why Lisp machines dies off coinciding with the usage of caches (particularly I caches) in those kinds of computers. At that point the hot path of the interpreter can totally live in I cache, so it's not polluting system bandwidth the same way anymore, and now the biggest reason in favor of a dedicated lisp machine is moot.
This work in the article is actually really cool and goes way beyond any lisp machines by off loading GC to another independent unit that runs in parallel to the main CPU, interleaving into the regular system memory bandwidth in a clean way.
Correct memory management needs information on the allocation context, in some cases, it can be handled automatically by a framework (like a game engine) or manually by the coder, but it is really cumbersome to force this into the language...
In my opinion, garbage collection is a bane.
I program professionally in Scala and without GC, the paradigm of strong FP would be (almost) impossible. Fortunately, the JVM handles this pretty exceptionally.
I think a GC in hardware is a fantastic idea and hope Intel and others incorporate it into x86-64. I don’t know how practical this is as I’m not a hardware guy, but a hyper-efficient pauseless concurrent GC that could keep garbage out of the cache sounds like a massive win in my book.
Typo: s/runtime/compile time
Also, this isn't particular to FP; every style of programming requires dynamic memory management for real-world programs (modulo pedantry about embedded programming).