I’ve spent this past week trying to become familiar with Go. Though it was a relatively positive experience, there were a few things that stuck out, especially coming from a python and javascript background.
When I first installed Go, the process was painless. I’d even say that it was the easiest language I’ve installed to date, requiring 3 commands that are clearly listed on the installation page.
Though in general my experience was great, there were a few glaring details that I ran into over this past week that have made me unsure about Go.
1. Go isn’t as stable as other languages.
There were a couple edge cases that I ran into that either seemed to produce logical fallacies or just cause the binary to silently crash. In one case, I wasn’t able to get two empty slices (go’s term for a linked list) to be deep equal. I spent at least two hours trying to reproduce the exact case, and I wasn’t able to. In the end, I just became incredibly frustrated. The most glaring issue was it seemed that a package I was using started to hide errors that were being thrown in my code, which caused some extremely freaky and strange behavior. Many may say that both of these issues were user-error, which could very well be true. Nevertheless, I’ve never had issues like these in any other language I’ve used for the first time, which is why I feel it’s worth mentioning.
2. Go isn’t really functional or imperative.
Go advertises that it is not a functional language, with map, reduce, and filter nowhere to be seen. Originally, I though this would be horrible, but it isn’t as bad as I would have thought. Just like switching from the old way of doing things (c) to using functional idioms like map/reduce, the change just required a differing perspective. However, that being said, map/reduce was created for a reason, and, in general, it produces nicer-looking and shorter sections of code that are easier to comprehend. Map/reduce in the Go native libraries is something I’m looking forward to seeing in the future.
At the same time, Go isn’t really imperative either. While methods can be bound to structures, classes don’t exist in the typical sense of the term. By deciding to leave out core concepts from both functional and imperative languages, I’m not exactly sure what the “go way” is to do something.
3. Go has no Package Manager
Go’s biggest downside right now is the lack of a real package manager. Installing dependencies in Go is relatively simple: go get github.com/user/package. However, there are a few things that are wrong about the way go has decided to deal with them. First, because (by default) each package is pulled from master, there’s no guarantee that backwards-incompatible changes won’t be pulled in remotely. Go doesn’t use semver or anything similar — packages don’t even contain a manifest file like a package.json or Gemfile — so there isn’t a “typical” place for version information to go*. In go’s defense, they’ve recently convinced the creator of Ruby’s bundler on board to design a new package manager from scratch for Go. Until that happens, the only way we can ensure packages are pinned to their correct versions is by checking them into source control.
* Yes, pun intended.
Therefore, will I be using Go everyday from now on?
To be fair, Go gets a lot of things right. Pointers are done sensibly. Types are easy to understand when reading the code and have helped reduce errors as I work. (This is coming from someone who normally uses dynamically typed languages.)
Nevertheless, no, not yet. Once Go has an official package manager and has matured as a platform, then I can see myself really loving the language and the community behind it.
Do you think I’m looking at Go the wrong way? I’d love to hear your experience and opinions in the comments below.
This post was inspired by my weekly hack ph.
Note: There’s a lot I didn’t have time to take a look at in this past week; a few of these being go functions, futures/promises, and interfaces so keep that in mind when reading.