I could have forgiven nil checks, but nil checks on interfaces elevated nils to a whole new level, which is annoying, but I do get where they were going with this: you should never nil check an interface. After all,an interface could be valid for a nil value.
There are ways to decently write go and not deal with nil, but as usual, linters defaults makes it impossible and you have to fight with your team before they will understand (we did this at some point and it was a huge improvement).
Don't use pointers at all, always allocate structs on the stack, pass them by value.
You pay the copy price, even with large structs, and that's fine. When there are exceptions, be very explicit about the reason: performance must be critical,not just an optimization.
Don't ever check interfaces for nil, if you need some sort of optional parameter, make a separate function and make it pass an valid object for that interface that's a null object.
These two did improve things substantially
This is the mess a language lands on when it conflates optionality (a semantic concept) with references/pointers (purely a machine concept). In Go, the requirement "need (non-optional) a reference to an object" is simply not expressible. This is a solved problem in other languages, for example `&T` vs. `Option<&T>` in Rust.
In C++, that distinction supposedly exists. References should never be null, while pointers can be. But there's no enforcement.
int& ref = *ptr;
ought to generate a panic for a null pointer. But it doesn't. They were so close to getting it right.
What the article said applies to Rust ref vs ref-option too.
Don't forget mutability! Go throws that on top too.
This is good advice for humans: they can quantify to decide "too many nil checks" or not. But it's not good for agentic coding, which we're entering the age of. Although agents are the worst they'll ever be right now, they're never going to be great at quantifying too many nil checks. I think we'll have to get used to far more nil checks than even bad programmers put in. But that doesn't matter to agents, they've got infinite attention spans, no cognitive bias and large working memories. Sonn we'll see no nil checks.
Also known as contract programming vs. defensive programming. This argument is very old, is not specific to golang, and I have found myself on both sides at different points in my carreer.
Delegate all `nil` and bad input checks to a validation framework and use it in all your constructor functions.
I’ll go you one better: integrate it into your language and have the compiler enforce it for you!
What about wrapping nil in a Maybe or Option type?
In this case, the missing piece in Go is the NonNullable hint. That would make it clear that null checks aren't needed, enforceable by the type system, and lintable.
Option types just forces you to do the check, but doesn't remove the need for it.
Now that we have generic types, a NonNullable intrinsic type seems doable...
References like C++, maybe?
Or a set theoretic type system with union type declarations (foo|null), like in TypeScript.
This is more about a hard dependency which causes a function to early exit