The One Thing I'd Change About Go
Go is built for grug brained programmers like me.
grug brain developer not so smart, but grug brain developer program many long year and learn some things although mostly still confused
apex predator of grug is complexity
complexity bad
say again:
complexity very bad
you say now:
complexity very, very bad
given choice between complexity or one on one against t-rex, grug take t-rex: at least grug see t-rex
The Go team took many years to add generics to the language. It was a good addition, and many argued that it was an obvious decision that should have been made sooner.
I disagree.
The simple truth is that when you’re building applications, especially back-end web applications or CLI apps (which is where Go shines as a language imo) you just don’t need generics all that often. They’re quite nice to have, but far from necessary.
Are you building a clever library using general-purpose data structures? Sure, generics make your life much easier. But let’s be real, I’m over here parsing JSON and shoveling strings into databases. I don’t need 3 layers of abstraction to get ’er done.
Smol-brain code work gud for application layer.
What else is Go good for?
Before I start shitting on my favorite language, let me point out some of the other reasons I love Go.
- Grug-brained syntax (already mentioned)
- Statically compiled binaries
- A toolchain with built-in formatting, testing and dependency management
- Dependency management built on Git repos (no npmjs.com or crates.io)
- A standard library that cares about the web
- Goroutines and channels (concurrency that doesn’t suck)
- Fast despite a garbage collector
What would I change about Go?
Not a hard question. It’s sum types! (Or enums, tagged unions, or whatever you want to call them).
Go currently has a shitty excuse for enums:
type Color int
const (
Red Color = iota
Green
Blue
)
They’re pretty bad. Go’s “enums” are verbose, error-prone, and don’t ackshually enforce much of anything from a typing perspective. Let me show you what I mean.
It’s just an alias
type Color int
This is a type alias. At the end of the day, the new Color type is just an int. It’s not really a new type, it’s just a new name for an existing type. In this world, every integer on God’s green Earth is a valid color.
That’s crap.
If I wanted that I would just use an int.
I want to restrict the set of valid colors to a specific subset of colors, e.g. Red, Green, and Blue.
iota
The iota keyword in Go is a special feature that allows you to define a sequence of constants that increment by 1. Sound useful? It’s not. It’s just cryptic syntactic sugar.
A smol-brained developer like me might make a few constants like this:
const (
Red Color = 0
Green Color = 1
Blue Color = 2
)
But a big-brained developer might save a few characters by using iota:
const (
Red Color = iota
Green
Blue
)
Here’s the kicker: the iota method uses the same amount of lines of code, but now I need to count on my fingers and toes to figure out the actual value of any of these constants.
const (
Red Color = iota
Green
Blue
Grey
Black
White
Yellow
Orange
Purple
Pink
Brown
Chartreuse
Mauve
)
What’s the value of Mauve?
Additionally, there isn’t even support to quickly marshal these integers into strings (e.g. for debugging) without writing mountains of boilerplate code.
Frankly I just pretend iota doesn’t exist and instead define string constants like a peasant:
type Color string
const (
Red Color = "Red"
Green Color = "Green"
Blue Color = "Blue"
)
Despite the verbosity, nothing is safe
Believe it or not, I can still do this in Go:
type Color string
var carColor Color = "clearly not a color"
The compiler don’t care. The Color type we made is just an alias for string. Any string is a valid Color. Sure, I defined some constants, Red, Green, and Blue, but they’re just constants that I hope and pray and beg my team to use.
I have no way to enforce this stuff at compile time. So now my only choice is to write runtime checks everywhere I use the colors:
switch color {
case Red:
// do happy thing
case Green:
// do other happy thing
case Blue:
// do other other happy thing
default:
return errors.New("wHY dIDn'T yOU uSe a vALID cOLoR???")
}
Eew, runtime.
If there’s one thing I hate more than indenting with spaces it’s doing literally anything at runtime.
How to make Go better
I can’t believe I’m using TypeScript as an example of a language that does something well, but here we are. In TypeScript, you can define a sum type like this:
type Color = "Red" | "Green" | "Blue";

Look at that. It’s simple. It’s elegant. It’s safe.
Sum types provide more type safety, more expressiveness, are easier to understand, all while being less verbose. It’s a win-win-win-win. If it weren’t for Go’s backward compatibility promise (which I love), I’d even rip out the stupid iota keyword in addition to adding sum types.
🚨🚨 BREAKING: TypeScript snatches defeat from the jaws of victory 🚨🚨
TypeScript did it. They have beautiful beautiful sum types. They’re called unions in TypeScript, but they’re the same thing.
Then some galaxy-brained 10x developer decided it also needed an enum keyword so we’d have 2 ways to accomplish the same thing:
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
Write Go.
Be grug.
Pray for sum types.
Related Articles
Format on Save in Go with VS Code [2026]
May 26, 2023 by Lane Wagner - Boot.dev co-founder and backend engineer
Go has hard opinions about how you should style and format your code. Setting up your VS Code environment to enforce the standard linting and formatting rules can save you a ton of time.
How to Become a Golang Engineer (on the Back-End)
Feb 23, 2023 by Natalie Schooner - Computer science educator and technical writer
“Guys, I’ve got an idea. What if we could design a language that’s easy to read like Python, but fast? That has a slim feature-set like C, but is good for web development? That’s compiled like Java, but doesn’t need a VM?”
Is Golang Best For Backend or Frontend Development?
Dec 19, 2022 by Natalie Schooner - Computer science educator and technical writer
Put simply, Golang is best for the backend side of a web application or website. There are many reasons that this is the case, so let’s dive in, but before we do, let’s cover some quick definitions.
How to Round a Float in Go
Nov 13, 2022 by Lane Wagner - Boot.dev co-founder and backend engineer
If you’re rounding a floating point number in Go, it’s most likely you want to format it in a string. Use the built-in fmt.Sprintf() function.