Go: How I learned to stop worrying and switch Programming Languages
I have been writing code for the past 8 years or so, out of which around 20 months have been, me writing code as a professional software engineer. In the years before that, I have tried my hands on a host of languages: PHP, JavaScript, JAVA, C++, Python and R. Early on, learning a new language always seemed to be a task and most commonly, the switch from a language to another was purely based on how cool a particular language was.
However, all this changed once I adopted JAVA in my professional workflow. The knowledge got deeper than what was seen in textbooks and personal projects. This had a much greater impact on my mindset, wherein I had developed a level of comfort with JAVA.
This reached to a point, where I tried to use JAVA instead of Python or C++ for solving random daily problems. Although I could do those things using JAVA, I began to suspect that JAVA was hijacking the muscle memory I had built for C++ and Python. Was I better at doing the same thing in JAVA?, doesn’t really matter. However, this thought of relying and depending heavily on a single programming language haunted me.
Cut to a new assignment where I had to migrate to Go. Go is different from JAVA in many aspects, however the most crucial of them is that Go is not your typical Object Oriented Programming Language. I was super hesitant at first, but the dynamics slowly changed and my fear of switching languages was now only present in my memories. In this small excerpt from my experience as a Software Engineer, I will be taking you through the thoughts I had while switching from a language I was really good at, to something completely new and interesting. I’ll be essentially comparing how I transformed from JAVA to Go, and how to spot similarities and differences. Let this be a guide for the readers (myself included) that helps them in transforming into a Software Engineer who is ready to take up language-agnostic development, right from the get go.
What is GO?
Go is statically typed, compiled programming language developed by Google. It is also blazingly fast to compile and execute. It is small, has an active release cycle and is being used by many companies to develop scalable, robust micro-services.What makes GO special?
Go is a language that has been built in the era of multi-core processors, whereas most other languages have been built in the era of single-core processors. Hence, Go is much more optimised for multi-core workflows comprising of concurrency and multi-threading and also provides a much more extensive arsenal of weapons to support the same. The binaries created for Go are extremely small and can be directly executed as executables, without the need of special, memory heavy JVMs as seen in Java based executables. This also makes Go very much optimised and successful for building micro-services.
My Journey of Transitioning:
1. Having worked on JAVA using Maven and Gradle, first thing I looked for was dependencies and dependency managers in Go. Go Modules is a Go maintained tool present as part of the Go Project, which in the current date and time, provides a similar experience, albeit with a few caveats and shortcomings.
2. Next step was looking for dependencies and choosing dependencies that were right for my use case. This is pretty easy to do as you are much more closer to the code, as compared to JAVA. In JAVA, Spring to be a bit specific, you import a library, provide configuration values and it is ready to go. However, when working with Go, a lot of that stuff has to be done manually, which also helps in understanding the processes from the ground up.
3. Next up was using a REST Client for developing APIs. JAVA frameworks come bundled with a TomCat or Netty server and auto-configured rest clients. Similarly, you need a framework for Go. Frameworks like Resty are good to get started with REST APIs.
4. Concurrency and Multi-threading: Arguably, one of the best and flagship features of Go. There is no ‘thread’ concept in Go, instead Go relies on abstracted threads called go routines and sub-routines. You can run a concurrent and multi-threaded workflow with just a simple keyword and Go will manage that pool without any manual intervention.
5. Rest of the stuff was just a lot of reading documentation and stack overflow :P
What did I like about Go?
Go brings functionalities that I have always missed while working with JAVA, some of those being:
1. The builds are blazing fast, 2–3s for a production project. Deployments are blazing fast too. Compare this to JAVA, and you’ll be looking at 2–5 mins easily.
2. The memory usage is very minimal, specially compared to memory hogging JVMs.
3. It has a very well built garbage collector, even after multiple stress tests, memory leaks are infinitely small.
4. You get to know the system from the roots, thanks to no auto-configuration.
5. Code execution is fast.
6. Best for the last, The learning curve is not as steep. One of the things that makes Go so desirable, is the bare bones functionality of it. This means that Go comes without any bells or whistles. There is no magic in Go, instead, you as a developer, are the magician.
There are a lot of benefits of choosing Go, however one also needs to take into account certain drawbacks and limitations that Go brings, some of them being:
- The community of Go developers is small compared to other languages like JAVA, C++, Python.
- If you are coming from a package or dependency manager like Maven, Gradle or NPM, you’ll find Go a bit different. Although, now Go does support such a functionality via go modules, all features are not present. I, too am waiting for release 1.18 for some new, much awaited features.
- Object Oriented Principles: Inherently, Go does not support OOP. Hence, no polymorphism. This results in messy method names. There have been instances where I have unknowingly implemented polymorphism in Go, only for the IDE to show me red lines. Also, no support for Generics (this will change, hopefully with the release of Go 1.18)
- No Auto Config or Plug and Play functionalities, which requires manually setting up database and client connections. This can lead to code redundancy across micro-services if you are not managing custom libraries.
- No support for conventional exception handling. Go does not support try/catch blocks. Also, there is nothing such as an exception is Go. You can propagate errors as a return value from objects and gracefully handle any errors.
- Debugging in Production is very hard if logs are not present at the correct places, since there is no JVM to manage application and heap memory for you.
Despite all these drawbacks, the pros that Go offers highly outweigh the cons, which will drop substantially as new releases come up. I have not seen any other community be that much excited about a new version of a language, as I have seen the Go developer community. This makes it all the more exciting.
Closing Thoughts:
Learning Go and adopting it in my Arsenal has been one of the best things that has happened to me as a Software Engineer. Although I am also working on JAVA, I am a fan of Go, thanks to its limited set of features. There is so much that you can do with Go, and the world is just getting started. I know which language I am voting for as the most developer friendly language this year.
I don’t dread changing languages anymore, and who knows, maybe there is one brewing up for me to try in 2023, or maybe tomorrow?
So, when are you considering adopting Go into your workflow?