At the time Go was created, it met one common definition of "memory safety", which was essentially "have a garbage collector". And compared to c/c++, it is much safer.
At the time Go was created, it met one common definition of "memory safety", which was essentially "have a garbage collector". And compared to c/c++, it is much safer.
This is the first time I hear that being suggested as ever having been the definition of memory safety. Do you have a source for this?
Given that except for Go every single language gets this right (to my knowledge), I am kind of doubtful that this is a consequence of the term changing its meaning.
If you go to the original 2009 announcement presentation for Go [1], not only is "memory-safety" listed as a primary goal, but Pike provides the definition of memory-safe that they are using, which is:
"The program should not be able to derive a bad address and just use it"
Which Go mostly achieves with a combination of garbage collection and not allowing pointer arithmetic.
The source of Go's failure is concurrency, which has a knock-on effect that invalidates memory safety. Note that stated goal from 2009 is "good support for concurrency", not "concurrent-safe".
Interestingly, in 2012 Rob Pike explicitly said that Go is "not purely memory safe" because "sharing is legal": https://go.dev/talks/2012/splash.slide#49. However it is not entirely clear what he means by that (I was not able to find a recording of the talk), but it seems likely he's referring to this very issue.
> "The program should not be able to derive a bad address and just use it"
My example does exactly that, so -- as you say, Go mostly achieves this, but not entirely.
> Note that stated goal from 2009 is "good support for concurrency", not "concurrent-safe".
My argument is that being concurrency-unsafe implies being memory-unsafe, for the reasons laid down in the blog post. I understand that that is a somewhat controversial opinion. :)
If you go back to the original 2009 announcement talk, "Memory Safety" is listed as an explicit goal, with no carveouts:
"Safety is critical. It's critical that the language be type-safe and that it be memory-safe."
"It is important that a program not be able to derive a bad address and just use it; That a program that compiles is type-safe and memory-safe. That is a critical part of making robust software, and that's just fundamental."
Note that this was not Rust's first stable release, but it's first public release. At the time it was still changing a lot and still had "garbage collected" types.
And while rust did have optional "garbage collected pointers", it's important to point out that it is not a garbage collected language. The ownership system and borrow checker were very much front-and-centre for the 0.1 release, it was what everyone was talking about.
Actually, my memory is that while the language had syntax to declare garbage collected pointers, it wasn't actually hooked up to a proper garbage collector. It was always more of a "we are reserving the syntax and we will hook it up when needed", and it turns out the ownership system was powerful enough that it was never needed.
AFAIK it was just an `Rc`/`Arc` with the possibility of upgrading it to an actual GC in the future.