Learning a new programming language: What I did differently when picking up Go?

Karisse Khoo
7 min readJan 16, 2025

--

Photo by Iñaki del Olmo on Unsplash

Introduction

In the realm of technology, there’s always something new to learn — be it a language, framework or tool. During my school years, we were taught Java and Python through the same structured approach: introducing the syntax for writing methods, for loops and other basics, followed by quizzes and projects.

However, when I started my first job after university, I had to learn Ruby on my own, which required me to create my own “learning structure.” Drawing from my school experience, I turned to interactive Ruby tutorials that broke down concepts like hashes, loops, and lambda functions into chapters, each ending with a quiz to reinforce the lessons.

Fast forward 3 years later, I took the opportunity to pick up a new language again! This time, it’s Go. In this article, I’ll share what I did differently this time, reflecting on what worked well (and what didn’t) when I first learned Ruby.

What I Learned from My Ruby Missteps

When I first started learning Ruby, I assumed that all programming languages were fundamentally the same. I believed that once I grasped the syntax, I’d be able to write code quickly and contribute effectively to my team. I could never be more wrong about this.

There were a few factors that slowed down my contribution at the start such as the lack of understanding for the language, and not taking the time to understand the business context and problems better. However, for the simplicity of this article, I’ll focus on the lack of understanding for the language aspect.

These were the 2 mistakes that I’ve made:

Mistake #1: Focused too much on familiarising myself with Ruby syntax

Yes, I became familiar with the Ruby syntax through the tutorials, however, I still struggled to write code that was considered “readable” and “maintainable” by experienced Ruby developers. For example, there are some idiomatic constructs that are preferred as they are considered to be more readable and expressive. Hence, more aligned with the practices for Ruby.

Mistake #2: Not reading enough code to understand the practices for Ruby

Instead of taking the time to read and learn from existing Ruby codebases, I dived straight into writing code. While my code worked, it didn’t meet the standards of being “production-ready.” This oversight resulted in lengthy code reviews as I struggled to align my contributions with established Ruby practices. Consequently, it took longer to produce “production-ready” code and get my work merged to production.

The key takeaway for myself here was that understanding the syntax of a language should not be the top priority to be able to contribute effectively. I needed to invest time in understanding the principles and philosophies behind them instead, to help me be more aligned with the language’s conventions and practices. Reflecting on these mistakes, I realised that I needed to refine my learning process.

Refining My Learning Process for Go

With Go, I refined my learning process and adopted these 5 methods to help me learn more about Go in the past 2 weeks which I’ll elaborate more on in this section:

  1. Method #1: Pick up a book to read
  2. Method #2: Reinforce learning through YouTube videos and more materials
  3. Method #3: Build a simple application and get my hands dirty
  4. Method #4: Read more code
  5. Method #5: Refactor code

Note: Although the examples in this section focuses a lot more on Ruby and Go, these methods mentioned can be helpful in picking up any language (or even frameworks)

Method #1: Pick up a book to read

Throughout these 3 years of being an engineer, I’ve come to realise that books hold a sea of knowledge that are just waiting to be uncovered. I settled on Pro Go by Adam Freeman with these 2 goals in mind:

  1. To grasp the common concepts in Go — understanding when, why, and how they are applied in real-world scenarios
  2. To gain awareness about the principles and philosophies essential for writing a Go application

Here’s a summary of what I learned from using a book as a learning resource compared to an interactive coding platform:

Reading a book

  • There isn’t a concept of inheritance in Go (this was the biggest 🤯 to me). Instead, composition is encouraged through the use of concrete types
  • There isn’t a concept of classes, Go uses functions, types and interfaces instead as it has a different take on object-oriented programming (OOP)
  • Pointers to manage memory allocation
  • …many more

Interactive coding platform

  • Writing a for loop in Ruby
  • Common search methods used in Ruby e.g. .one?, .any?
  • Hash syntax in Ruby e.g. Hashes with symbolized or stringified keys

I found that having a book as a resource provided not just syntax and usage patterns, but also offered a more in-depth learning experience where I not only got to learn about the what and how that interactive coding platforms provide, but also the when and the why behind the concepts.

Caveat: If you’re new to programming, starting off with the interactive coding platform could be more beneficial. However, if you’re already an experienced programmer, I found that reading a book could give a better head start.

Method #2: Reinforce learning through YouTube videos and more materials

At this point, it was pretty evident to me that Go was fundamentally different from the languages I was accustomed to since it doesn’t have the concept of classes and inheritance. This means that my approach to writing Go needs to shift slightly, that’s when I chance upon a well-explained video by Anthony on how we should think differently when writing Go especially if you’re coming from a different programming language background.

Understanding the principles and philosophies behind writing Go code was also important to me to address the mistake highlighted in Mistake #1 in the previous section. I discovered a document by Dave Cheney where he shared about writing maintainable Go application, which I found to be a very good reference document to refer to and I imagine going back to it every now and then as I get a hang of Go.

Method #3: Build a simple CRUD application and get my hands dirty

This approach closely mirrors the “project” aspect of a school curriculum as I find this was one of the best ways to validate my understanding by applying what I’ve learnt from Method #1 and Method #2.

The main goal here is to start small and simple by creating a CRUD application. By keeping it small and simple, this helps me to focus better on getting the functionality to work first, without worrying too much about writing perfectly clean and maintainable code — those improvements can come later. Fat methods? Duplicated implementations? No worries, we can always go back and improve on them later.

By getting my hands dirty, I’ve also discovered a few random gotchas for Go which deepened my understanding of how I could put them into practice better. Some example gotchas that I came across were:

Uppercase and lowercase conventions

  • Lowercase for private fields and uppercase for public fields
  • Uppercase methods can be exported and used by other packages

Zero values of pointers

Although structs do not have an “empty” value, struct pointers do, with the empty value being null. For example, adding the* pointer to PercentageDiscount has a different value as compared to Price when the fields are not initialised. Price returns 0 as it’s the zero value for float64, and PercentageDiscount returns null as it’s the zero value for pointers.

Method #4: Read more code

This is how I made amends to my Mistake #2 and is probably one of my biggest takeaways in the early stages of my career where I shouldn’t only be focusing on writing more code, but also on reading more code.

Reading more code has helped me in several ways:

  1. Learn how to navigate around the codebase better
  2. Validating my understanding of what the code is doing (thankfully, we now live in the age where ChatGPT exists so there’s your friend if you need some help!)
  3. Identify some common design patterns that I can adopt to improve code maintainability

You may ask where can I find more code to read? In my opinion, the best way to start is by looking through open source code of popular libraries/packages. For example, I chose the mux package since I was already using it to handle HTTP routing in my CRUD application.

Method #5: Refactor code

Lastly, I refactored the code that I wrote in Method #3. This gave me the opportunity to revisit what I felt was lacking and improve on them such as reducing code duplication and following Go’s conventions more closely while applying my learnings from the above mentioned methods.

Conclusion

In conclusion, learning a new programming language goes far beyond than just knowing the syntax. It’s also important to understand the “when” and the “why” behind the concepts which can be learnt through picking up a book, being more hands on, and exploring more codebases.

The key takeaway is that learning never truly ends — there’s always more to discover, and every mistake is an opportunity to grow ✨

--

--

Karisse Khoo
Karisse Khoo

Written by Karisse Khoo

Software Engineer based in Singapore. Knowledge is wealth, I write to share about all things related to Software Development https://karissekhoo.netlify.app/

No responses yet