IOW: it describes how reference counting may reduce the overhead of “true” garbage collector. The final goal is never disputed.
They won in the same sense as microkernels have won. Remember that piece?
Yes, by pouring enough billions into propaganda of “one true solution” tracing GCs have become ubiquitous.
On desktops and our smartphones, that is. But would that last? Only time will tell.
But I suspect even their proponents expect that this “victory” wouldn't last and are preparing to say that they have “won” even if that would happen!
And yet they feel the need to redefine term GC and forcibly include something sensible and usable into it, too.
Don't you find that… ironic? I suspect that proponents of tracing GC just want to declare “total victory”: if languages like Rust would replace C then they may preach that everyone uses GC of one form or another and then try to push tracing GC on the unsuspecting audience.
Yes, that's how it was used for years. GC meant “tracing GC”, “true GC”, not that limited ARC scheme. But around 20 years ago definition started to change and people started including pure reference counting into “GC” notion. Why? What's the goal? Why would you want to do that?
The trouble is that every tracing GC, inherently, declares that it's something unique and have the right to treat everything else as something subservient.
Everying in your process become a movable object which is structured like GC wants to structure it. Your whole world become built around that. And if you want two such runtimes? Like: and Android app build with Unity and with some Go libraries for communications? Pile of kludges and then even bigger pile of kludges.
Tracing GC refuses to play nicely with anything. Everything that was simple before introduction of tracing GC becomes extremely complicated. Compare with manual memory allocation strategy (every .DLL library in Windows world have it's own, personal, memory allocator and they nicely coexist) or ARC (you can link Rust and Swift modules easily and they don't ever need to know about the means other piece of your app uses).
Tracing GC is anti-encaprulsation, anti-open-closed principle, anti-single-responsibility principle, anti-interface-segregation-principle and so on! It volates literally every single principle that OOP proponents say are important… and what for? To ensure that if you ignore memory management your app may get a tiny chance to not become a memory leaking hog? Is it really worth anything?
I know one use-case where GC is useful: things like theorem provers where we don't know, in advance, what would happen in the end and, more importantly, are happy to accept spurious failure.
For 99% of progams, though, tracing GC is literally “a solution in a search of program”: it doesn't give you any capabilities worth paying for yet demands a lot from many other components.
Mudlling the water and conflating ARC and GC makes perfect sense if you want to hide that problematic nature of GC: if you forcibly declare that ARC is a GC, too, then you may happily tell to everyone that all these problems with GC may be easily overcome (say, e.g., you may switch to reference counting GC if they worry you so much) and then turn around and continue to push tracing GC, anyway.
For me the definition of “true GC” have become precisely that: ask yourself question “may I link that module with something written in foreign language without telling that foreign language about how my GC works” and if the answer is “sure, just use FFI” then it's not a “true GC”.
Precisely because “true GC” have to know about everything in your app. That is the line that I don't like to cross.