|
I'm no Go expert, so the following may just come from having not used it enough. The two things that shocked me out of continuing with Go were exception handling and package management. Exception handling is basically not implemented. Instead the Go developers dediced to add half a step from return codes towards exceptions and work with that. And now the community seems to have decided to just reraise everything that comes their way. Nobodoy seems to see that such a simple basic feature shouldn't require a piece of code, it should be done automatically by the language. And the community doesn't seem to see why it's nearly impossible to debug. I really hope that Go developers have some secret tools I just don't know about, because there are no stack traces, and on the abstraction level of a user getting an error from an underlying framework printed out doesn't really help at all, especially when the code seems to continue after printing the error (making it a bug, by reporting a warning as an error). My favorite example is kubernetes helm reporting a connection error in my job's infrastructure, every time you use it, but after that error it actually switches from IPv6 to IPv4 and just works. But still it feels good about reporting that error. wtf. The next thing is package management. I had high hopes here after going through the trouble of working on that topic in 2012 when the Python community was developing its package management. I mean if you don't add that on top of an existing world, but create it from scratch, there is a chance to just do it right and not have to bother with all the pains of legacy systems, right? Well, Go decided it doesn't need versioning on imports. Just put the Github link there, don't even choose a branch. How can any code ever get finished that way? My best guess is that now they have to develop stuff on top of that already-born-as-legacy system and also try to integrate that with their core. Sad. I really hope someone can add some corrections to this view. |
As far as package versioning, what we ended up doing is vendoring everything into our source-control system. This fits our use better all around. For our production systems, we don't want inequality bounds on our library versions. We have tested our system with version X, we only want to ship with version X, not, X.1 or X.2. Vendoring allows us to pick a specific version. Admittedly, this makes more sense in the Go world, where executables tend do be statically compiled.
Vendoring makes it trivial to track local changes to code in our dependencies, and ship them upstream when appropriate. It makes new developer setup simpler. Finally, the Go toolchain has support for vendored code that makes the setup relatively painless. And near instant compilation means that you don't have to wait very long for your dependencies to compile.
[1] https://golang.org/pkg/runtime/debug/#PrintStack