Frontend Labs
⋯

Part I — Foundations: the Go way

The language itself, in order: what problem it was built to solve, the toolchain, and then the pieces every Go program is made of — types, control flow, the error-handling pattern that shapes all Go code, and just enough of slices and maps' internals to explain the bugs you'll eventually hit. Two terminal projects at the end put it all to work before Part II adds concurrency on top.

1. What Go is, and why it exists

1.1 The problem being solved

Go was created at Google in 2007–2009 by Robert Griesemer, Rob Pike, and Ken Thompson, in response to a very specific pain: Google's C++ services took tens of minutes to build, dependency graphs were tangled, and the languages available (C++, Java) made concurrent, networked systems hard to write safely. They wanted a language with the safety and readability of a garbage-collected language, the fast compilation of an interpreted one, and concurrency as a first-class citizen instead of a library bolted on top.

1.2 The design goals, and how they show up in the syntax

Goal Consequence in the language
Fast compilation No header files, no generics until 1.18 (kept simple even then), strict unused-import/variable errors so the compiler never guesses
Readability at scale One way to format code (gofmt), no operator overloading, no implicit conversions
Safe concurrency Goroutines + channels as language primitives, not a library; the race detector is built into the toolchain
Simple deployment Single-file binaries are common; pure-Go builds are often static, while cgo builds may depend on system libraries
Explicitness Errors are values, not exceptions; nothing happens "automatically" except defer, GC, and slice growth

1.3 What Go deliberately does not have

No exceptions (only panic/recover, reserved for truly exceptional conditions), no classes or inheritance (only structs, interfaces, and composition), no operator overloading, no implicit numeric conversions, and —until you explicitly opt in with generics—no generic containers. This is not an oversight; it is the single biggest reason a large, multi-team Go codebase stays readable after five years. A Go file you've never seen still looks like every other Go file.

1.4 War story

A team migrating a Python API gateway to Go expected the rewrite to take three months. It took six weeks, and the resulting binary went from a 150MB Docker image with a Python interpreter and dependencies to an 18MB FROM scratch image with a single static binary. The surprise wasn't performance — it was that code review got faster, because there was no longer a debate about "should this be a decorator, a metaclass, or a mixin." In Go there's usually one obvious way to write a given piece of logic, and reviewers spend their time on the logic instead of the style.

# The whole "hello world" loop
mkdir hello && cd hello
go mod init example.com/hello
cat > main.go <<'EOF'
package main

import "fmt"

func main() {
	fmt.Println("hello, go")
}
EOF
go run main.go

Generated from real-life-golang-guide.md · 8 Oct 2026 16:36