For at least some problems people will not want to use a GC, and D's story there isn't as good as Rust's.
For at least some problems people will not want to use a GC, and D's story there isn't as good as Rust's.
However, the garbage collection in D turns out not to be an issue in practice. In D, you do have destructors and deterministic deallocation when you want to (in one word: RAII).
Eh. Often the whole "ownership" thing is irrelevant. For a lot of high-level programs, trying to express things in a Rust-ish "ownership" style with pointers adds a lot of syntactic and semantic overhead.
I don't see how it can ever be irrelevant, unless you use immutable data structures everywhere. Does your class/struct provide getters? Ownership! You have to think about what you return. When you are not careful, the calling code can break invariants of the data structure. Consider the following Go code:
type Foo struct {
sortedSlice []Bar
// ....
}
func (f *Foo) sorted() []Bar {
return f.sortSlice // Outside world can break invariants.
}
Now the outside world has access to internal state and can break invariants (make sortedSlice unsorted). You have to decide to: make a copy (and waste time) or document this fact (and put the burden on the user of Foo). Suddenly, knowing from the signature what the ownership is and having the compiler fail on violations, looks pretty useful!Tony Hoare once called the null pointer his one billion dollar mistake. I think the lack of ownership semantics (or immutability) is an even bigger mistake. Some of the most difficult and aggravating bugs that I encountered (even in relatively simple web services) were caused by (a lack of understanding of) ownership. Throw in some concurrency and you have bugs that occur frequently, but are terribly hard to reproduce consistently.
How does that avoid race conditions? What happens if I quickly move my pointer around? i.e. b=a;a=null;c=b;b=null;d=c... etc
Garbage collection trades the problems gc brings with less program complexity and programmer time. It's a degree of freedom that one can choose (if one can choose the language one uses).
"Reserve memory for this entity when I declare it and release it when I don't seem to be using anymore" is huge leap in getting computers to assist us in our tasks. But sure, there are lot of problems domains where this is not a good thing.
Now you can build systems that detect cycles who lack ownership outside of the cycle and break them. We call those systems garbage collectors.
GC is indeed a hack: it approximates an infinite memory system on systems that have finite memory. Reference counting is a worse hack: it approximates a GC on languages/systems that can't afford a real GC.
And I say this as a C++ programmer that has written very little code on GC'd languages.