Depending on who you talk to, reference counting is garbage collection. Industry tends to mean "tracing GC" when they say GC, academia tends to mean "all runtime automatic memory management schemes".
I might be totally off-base, since unlike you I have no background in compilers, language runtimes etc, but I was under the impression that Swift's ARC is compile-time, which would make it not GC'ed by either of your definitions, whereas runtime ARC, like PHP's implementation, would fit the second.
So, imagine an interface to a reference counted thing. You have two methods:
rc.add()
rc.subtract()
Add bumps the count, subtract drops the count down. When the count hits zero, the thing is deallocated.
What Swift's _automatic_ reference counting is insert the calls to add/subtract _for you_, so that you don't need to do it. But fundamentally, they're still there. So the decision of "when does this get deallocated" is still a runtime thing, even though those calls are compiler inserted.
Thanks for the info, and for the very clear explanation!
Obviously, even in C the memory management is a high-level runtime abstraction of sorts (neither the programmer nor the compiler is choosing the actual addresses in memory to alloc/dealloc), so at what point on the continuum of C++-style RAII, Obj-C RC, Swift ARC and so on would you say "garbage collection" comes into play? Is it just one of those "I know it when I see it" type things?
So, one of the reasons this is a bit muddy is that historically speaking, it was much more clear. You had languages which did some kind of "automatic" memory management, if that was through a refcount system of some kind (Like Python was (is?)), or a tracing GC (like Lisp was/is, or Ruby, whatever). And then you had languages which had some sort of "manual" memory management, where you explicitly allocate and free heap memory. I think that the real distinction here is "does runtime state decide if something gets deallocated"? If so, then that's garbage collected. If not, then it's "manual".
But languages like Rust and Swift sort of bend this, and I see them as coming from each side, looking in. So Swift is like a GC'd language that's not _quite_ GC'd, while Rust is like a manually managed language that's not _quite_ manually managed. They feel a bit different.
Thanks again; very interesting stuff, and I feel like my understanding of the concept here is quite a bit better now. It'd make a good blog post, I think. (I'm probably the only person seeing this convo).
It's a great skill to be able to explain pretty complex topics in "layman's" terms; I don't think I'm alone in having the experience of posing a question to an expert, getting a jargon-heavy answer that takes 30min of Googling to parse (or a condescending one that assumes I'm unfamiliar with basic CS concepts), and left feeling foolish for asking. So kudos to you! :)