# Is reference counting GC vs. tracing GC a language property or an implementation property?

We sometimes hear "Swift doesn't do classic (tracing) GC, it uses ARC."

But I'm not sure if there is anything in the Swift semantics that requires reference counting. It seems that one could build one's own Swift compiler and runtime to use tracing GC.

So what exactly is "reference-counted" about Swift? Apple's implementation or the language itself? Are there parts of the language or the library that so strongly support ARC that we can use that label for the language itself?

Swift guarantees that once the last reference to an object is dropped the object is deinitialized, and the deinit code is immediately run.

Obtaining this kind of guarantee through GC is not possible - at least, not without sacrifying performance. Standard GC mechanisms only ensure the deinit code is eventually run, e.g. at the next GC cycle. For precise semantics, you need a reference count somewhere.

• Ah, so the presence of deinit as a keyword and its associated semantics are indeed the things that put reference counting squarely in the language, rather than the implementation, realm. – Ray Toal Dec 21 '15 at 16:50
• Nothing prevents a GCed runtime to check for unreachable objects whenever something is deallocated. It's just horribly inefficient. – Raphael Apr 13 '17 at 20:21
• @Raphael Edited to be more precise on that point. – chi Apr 13 '17 at 23:25

Is reference counting GC vs. tracing GC a language property or an implementation property?

reference counting GC and tracing GC provide the programmer with different gaurantees.

Reference counting provides determinism in the location in the program flow where an object is destroyed, that can be important if the object owns scarce resources that must be freed quickly. On the other hand it can't deal with cycles of "strong" references.

It is up to the specification of an individual language what if any characteristics are gauranteed and therefore which choices are available to a compliant implementation.

• It's also possible to combine refcount and GC. Then the language may document that objects have their destructor executed as soon as they're unreferenced (implying refcount in one form or another) and that reference cycles will be destroyed up eventually (implying some form of GC). Alternatively, the implementation could do this while the language doesn't guarantee when destructors are run (IIRC that's the case of Python and its reference implementation), in which case it would be an implementation property. – Gilles 'SO- stop being evil' Dec 21 '15 at 19:50

You could take the language known as Swift and rename it to "Swift with ARC". You could then create a new language named "Swift with GC" with exactly the same syntax, but with fewer guarantees about when objects are deallocated.

In Swift with ARC, once the reference count is 0, the object will go. With garbage collection, as long as you have a weak reference, you could assign that weak reference to a strong reference to "recover" the object. (In Swift, once the reference count is 0, weak references are nil); that is a major difference.

And of course Swift with ARC guarantees that killing the last reference count will deallocate the object immediately. For example, you might have a FileWriter class, where you are not allowed to have two instances writing to the same file in existence at the same time. In Swift with ARC you could say oldWriter = nil; newWriter = FileWriter (...) and you would know that the new FileWriter is only created after the old one is deleted (unless you kept another reference around); in Swift with GC this wouldn't work.

Another difference is that in "Swift with ARC", objects that are only referenced through strong reference cycles, but not actually reachable, are guaranteed to be not deallocated.