> Sorry for being annoying. I wasn't trying to be.
Thanks, no worries.
You're right that Java doesn't have this performance problem because it (apart from primitives) has no implicit copies. (So the code wouldn't copy, it would return a reference, hence no allocation.)
I think what you're trying to say is: programs written languages with value semantics can implicitly create more objects, which (in some cases) have additional allocation/lifetime tracking in languages with automatic lifetime management. So maybe one solution is to prevent copies in most circumstances, and when you do need to copy, make them explicit.
But I think this conflicts with Go's philosophy as well. First, in highly concurrent programs, copies are necessary. A mutex/atomic will become a bottleneck; sharing is bad for performance. This means that copies should be part of most types in the language. (If they aren't, you'll run into issues like not being able to pickle when using multiprocessing in Python [1].)
OK, so we need copies. But clearly, I shouldn't have to write `a = b.Copy()` if b is an integer. That's too verbose. And if everything has a `.Copy()` call, that leads to visual noise and it's not clear when copies are actually expensive. So what set of "blessed" types should be implicitly copyable? Java picks primitives, but this means it's basically impossible to create an int-like object with value semantics. I think this is bad. C++ is at the other extreme with "(almost) all objects are implicitly copyable" but some people dislike how forgetting a & on a std::vector type might lead to a huge copy.
Go has chosen a reasonable middle ground -- dynamically sized types like arrays and maps are not implicitly copyable, but "cheap" objects like structs are implicitly copyable. This means that when you see a Copy call, it's meaningful. But this means you run into these situations when an implicit copy interacting with lifetimes/garbage collection causes a slowdown. But I don't see any other alternative. Getting rid of implicit copies for cheap types will cause visual noise. Getting rid of GC makes your language harder to use. Both of these alternatives seem worse to me.
To be clear, I'm not a huge fan of Go. Especially around the lack of monadic error handling. But I think they have done a decent job wrt. their design goals.
[1] https://stackoverflow.com/questions/8804830/python-multiproc...