Thoughts as I intro to golang pt. 1

I started learning Golang this weekend. I’ve ~tried a few times before, but not very hard. What’s new this time and helping me learn:

  • I know more about programming, so it’s easier to recognize and quickly process concepts. I’m realizing that a lot of concepts that folks portray as Golang-specific aren’t actually Golang-specific. See below.
  • I’ve done other tasks in other languages, so I think I see a specific application where Golang could be nice to work with. Specifically, I want to build a Telegram bot, and I think Golang’s rich standard/quasi-standard library for HTTP, JSON, concurrency, and channels will be very nice for this project.

Observations

What’s nice about Go

  1. Readable, concise set of Go-specific ways of doing things. For example, you just have “for” for loops.
  2. Explicit, idiomatic error handling not that bad? This doesn’t actually seem like that much of a drag because there’s only one way to handle errors. In Rust, slamming everything into a question mark doesn’t really feel idiomatic or safe.
  3. Good LSP. Make or break for a language. Rust, TS (is ~okay), Go.
  4. Concurrency and parallelism model. I get it. Non-coloring async with Goroutines + first-class channels + GC = really nice if you don’t need max perf. Probably something like 80/20, even 98/20 coverage for most programming use cases here.
  5. Intro/learning is very approachable if you’re intermediate. Now that I’m intermediate, this is nice :)

Seeming sharp edges

  1. Verbose. I think this can be a preference/sentiment thing. A very dense Rust expression feels very powerful sometimes, tedious other times.
  2. Single character variables names. WTF is with this convention. In practice, short variable names are not readable.
  3. Implicit mutability. Think this might be a preference thing. I really like the explicit mutability of Rust (both at the declaration and borrowing level).
  4. Want my enums, want my Option. Option feels sooooo nice. E.g, validating a required float field in a JSON response with go-playground/validate looks for 0.0 after unmarshaling. I guess in practice it’s probably fine but it feels nervous.

Golang concepts that can be explained in other ways

Goroutines = first-class async. This feels like the easiest way to explain this concept yet I’ve never seen anyone put it this way? You ask someone to explain Goroutines and they end up in all kinds of irrelevant rabbit holes: “oh well it’s like a lightweight thread” or “no you don’t use the async keyword” or “well remember that concurrency =/= parallelism.” Stop!

The go keyword for Goroutines identifies that a function is async. Go abstracts everything related to async (awaiting, futures, blocking/yielding, polling, et. al.), and the Go runtime manages it for you, so the DevEx is like writing synchronous code. This is something like if Tokio were actually part of Rust, plus you had different language philosophy, plus you GC’d.

Package namespaces avoid duplication to a central facility. Coming from Rust and Python, I remember I found it confusing to import packages directly from Github rather than by unique package name. But actually, it’s very nice and intuitive and avoids desynchronization of actual code from the package manager.