My impression on Go after just one week Link to heading

I have been curious about Go for a while, and I finally decided to give it a go last week. I quickly went through a beginner’s Go book to learn the basic syntax and then jumped straight into writing Gunzip in Go. Actually, it was more like porting Gunzip written in Rust into Go. I spent a few hours a day and finished the program in just about a week. Here are some of my thoughts on Go during my short experience.

Go programming impression

The good Link to heading

  • Go is amazingly easy to learn. The language is very similar to C, but without raw pointers and manual memory management. With just one week of casual learning, I felt that I was as comfortable reading and writing programs in Go as in Rust in terms of syntax. I may not know much of Go idioms or standard library, but I felt like I could write Go code to do what I wanted to do — performance and quality of code aside. Likewise, I felt like I could pretty much read and understand most of Go programs out there. This is truly remarkable given that it took me probably six months to reach a similar comfort level in Rust. That’s about 20 times less effort.

  • Like other languages I love, Go is a statically typed and compiled language, as opposed to dynamically typed and interpreted languages. It is always better to catch a bug earlier during the compilation process than later at runtime. This is the reason I just can’t stand Python for anything larger than maybe 1,000 lines of code. Static typing enforces good code design and makes the code much more readable. Go comes with all the tools we need, from its dedicated debugger delve to its profiling library pprof. This makes it very easy to write, debug, and profile Go code. For comparison, Rust does not have native debugging support — though one can debug with gdb or lldb, these debuggers are meant for C/C++ languages and support for Rust is limited. This is one of the pain points I have for Rust. I suppose this is because Go is backed up by Google, whereas Rust is driven by the community effort.

  • Go offers unique and innovative concurrency features that set itself apart from other programming languages. Specifically, goroutines and channels really lower the barrier for writing concurrent and/or parallel programs and are probably the number one killer feature of Go.

The bad Link to heading

  • The error handling could be better. I definitely prefer the way Rust handles errors with Option and Result and how errors are propagated with the ? operator. Checking for errors manually every time is quite tedious and annoying.

  • The closest data structure to a dynamic array is a slice, and it reminds me too much of C. In C++, we have std::vector<T>. In Rust, we have Vec<T>. They are structs with methods that provide convenient operations, such as push, pop, resize, front, back, etc. In Go, all of these have to be manually implemented. Given that vector is probably the most commonly used data structure, I don’t understand why Go standard library doesn’t have it. As shown below, simple operations are much more verbose and tedious to write in Go.

// Go
xs := make([]int, 0)
xs = append(xs, 1)
xs = append(xs, 2)
x := xs[len(xs) - 1]
xs = xs[:len(xs) - 1]
// Rust
let mut xs = Vec::new();
xs.push(1);
xs.push(2);
let x = xs.pop()?;
  • The performance isn’t as good as C, C++, or Rust. This is expected given that Go has automatic memory management. If you want maximum performance, you shouldn’t write in Go.

  • Gopher is not as cute as, say Ferris :(

In summary, Go is a well-designed language that is easy to use and reasonably performant. To me, it seems that Go would be a good language for new projects and prototypes that do not have strict performance requirements, such as throughput or latency.