It’s been about a year since I started using Go. I’ve written a lot of code with it, including an entire micro-service and a contribution to glide. I want to emphasize that, for the most part, it’s been pretty good. But about once a month, my eye starts twitching and I get the urge to start making a head-to-desk motion. The reasons for this can be pretty simply demonstrated. Since I seem to have this conversation on a regular basis, I thought I’d record my thoughts so I can just simply reference this the next time it comes up.
I need a data structure. It has the following requirements:
At first glance, we might be tempted to simply use a map like so:
This is kinda nice. In fact, it satisfies the first two requirements of our data structure. But since the very early days of Go, the order objects are stored in a map is random (for good reason). So I can’t do something simple like insert all the elements into the map in the same order over which I’d like them to be iterated.
Alright, no big deal. We can get around this by just writing a little bit more code, using an array to keep track of order.
Now whenever we want to iterate over the map, we need to iterate over the Order slice instead, using the strings we pull off as keys into the map. Not the greatest, but it works.
This is where things get really hairy. Go doesn’t have the concept of runtime constants. If we want things to be immutable after we create them, we’re going to have to completely, and I mean completely, encapsulate both the slice and the map in our struct. This is because maps and slices have pass-by-reference semantics. In other words, if at any point I give you a reference to them, you’ll be able to modify them. The best I can come up with is now this explosion of code:
What just happened? That’s an infuriating amount of code to write. You know how much code I’d have to write if this were C++, C# or Java? None. They all have reusable notions of an immutable, ordered map. Yet in Go, every time I need one I have to write 30 lines of code. I feel like I had to fight to Go every step of the way here. I feel sad.
Go has some pretty neat concepts. I love that it enforces composition over inheritance. Goroutines are pretty nifty. I’ve been pretty satisfied with it overall. But time and again, I find myself solving the same problems over and over when using Go. I find myself completely blocked, with no way to write DRY code².
I’d love to see the Go community address issues like this. IMHO generics would solve all of the issues above, but I understand that’s somewhat of a sore topic for the Go community. Perhaps something like a simple form of codegen for common data structures and algorithms?
Kurtis Nusbaum is a Mobile and Backend Developer at Uber. He’s an avid long distance runner and diversity advocate. He can be found on Twitter and LinkedIn. Here’s his github. You can subscribe to his mailing list here. If Kurtis seems like the kind of guy with whom you’d like to work, shoot him an e-mail at [email protected].
¹Here’s why you might want immutability.
²For instance, try writing a reusable exponential backoff algorithm or a reusable binary tree. Oh, and you can’t use interface{}. We’re programming in a statically typed language for a reason.
Hacker Noon is how hackers start their afternoons. We’re a part of the @AMIfamily. We are now accepting submissions and happy to discuss advertising & sponsorship opportunities.
To learn more, read our about page, like/message us on Facebook, or simply, tweet/DM @HackerNoon.
If you enjoyed this story, we recommend reading our latest tech stories and trending tech stories. Until next time, don’t take the realities of the world for granted!