Back to Writing
Growth status: Seedling SeedlingUpdated: Feb 5, 20265 min read

Go Does Not Care About Your Feelings

"Code is for the machine, not your ego” might as well be the unofficial Go motto right next to: "We removed that feature because you might misuse it."

image

I came to Go with the usual developer instincts I wanted elegance I wanted cleverness I wanted to feel smart

Go looked at me like a bouncer at a quiet bar

Go doesn’t argue. It just stares at you blankly and says:

“No, you don’t need generics.”

“No, you don’t need exceptions.”

“No, you will format your code this way.”

“And yes, this is your fault.”

The Go compiler isn’t angry or sarcastic, it’s worse. It’s disappointed.

Minimal syntax, zero drama, and an iron belief that readability beats cleverness every single time.

It is a hard language to be clever with That is not a limitation That is the deal Go does not reward vibes It rewards finishing

The tooling is not a side quest

In a lot of ecosystems, tooling feels like a second job In Go it is the job and it is boring in the best way

I write code I run these Everything is where it should be

go test ./...
go test -race ./...
go fmt ./...
go vet ./...
go build ./cmd/app

Dependencies also behave like adults I add a package Go records it I clean the module The files stay honest

go get example.com/some/pkg@latest
go mod tidy

I like that the dependency story is two files and a stern tone go.mod says what I want go.sum says what I actually got No theatre

Static binaries feel like cheating

I build once I copy the binary It runs

This makes me suspicious at first Like surely there is a hidden ritual There is not

Cross platform builds are also oddly calm

GOOS=linux GOARCH=amd64 go build -o app-linux-amd64 ./cmd/app
GOOS=darwin GOARCH=arm64 go build -o app-darwin-arm64 ./cmd/app

It is the kind of simplicity that makes you forget you used to negotiate with runtimes

Error handling is a personality test

Go does not have fancy error magic It has you And the truth Right there Every time

f, err := os.Open("config.json")
if err != nil {
    return err
}
defer f.Close()

At first I thought this was repetitive Then I realized it is explicitness as a feature The code tells you where it can fail It does not pretend it cannot It does not hide the cost of reality behind a clever abstraction

Then you level up and start wrapping meaning into the failure

b, err := os.ReadFile("config.json")
if err != nil {
    return fmt.Errorf("read config: %w", err)
}

Now the error has a story Not just a scream

Goroutines and channels are power with guardrails

Go concurrency feels like it was designed by someone who has been hurt before It is simple enough to use And sharp enough to respect

results := make(chan int)

go func() {
    defer close(results)
    for i := 0; i < 3; i++ {
        results <- i * 2
    }
}()

for v := range results {
    fmt.Println(v)
}

It is clean It is readable It is also how you accidentally invent a deadlock and learn humility

Context is how you stay sane

Context made me stop pretending infinite work is fine Now I carry cancellation like a first class idea

func fetch(ctx context.Context, url string) error {
    req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
    if err != nil {
        return err
    }

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    return nil
}

ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()

_ = fetch(ctx, "https://example.com")

This is not fancy It is discipline that fits in your hands

Go embed is the kind of practical magic I trust

I like tricks that reduce moving parts embed does that

import "embed"

//go:embed templates/*.html
var templatesFS embed.FS

Now my templates ship with the binary No missing files No runtime scavenger hunt Just one artifact that carries its own furniture

The spec is short and the language stays out of my way

Go feels like a language designed to be remembered Not studied Not debated Remembered

I do not spend my time learning new syntax to express the same idea I spend my time removing complications I used to accept as normal

Go keeps asking one question Can someone else understand this quickly Including future me when I am tired and angry

The GC is not my hobby and I love that

I do not want to manage memory like it is a personality trait Go has a garbage collector It is not perfect It is not mystical It is simply there so I can build systems instead of building a second brain to track allocations

When performance matters I can profile and tune When it does not I can move on That trade feels honest

What Go is teaching me

Go is teaching me that simplicity is not a lack of ambition It is a refusal to cosplay complexity

It is a language that makes it hard to be clever So I can be useful

And the most surprising part I am enjoying it

Not because Go makes me feel smart But because it keeps me shipping things that work

Update History

Feb 5, 2026The tooling is not a side quest
Feb 5, 2026Static binaries feel like cheating
Feb 5, 2026Error handling is a personality test
Feb 5, 2026Goroutines and channels are power with guardrails
Feb 5, 2026Context is how you stay sane
Feb 5, 2026The GC is not my hobby and I love that

Share this writing

Backlinks

0 writings link here
No writings link to this yet