Hacker News new | ask | show | jobs
by mixedCase 3518 days ago
> Of course, there are ways around this such as returning a struct, but then that's no longer compatible with the error interface.

Which your struct can easily fulfill. That's the beauty of Go interfaces.

1 comments

The linked FAQ specifically talks about returning pointers to structs that fulfil the 'error' interface and why it's a bad idea.
It's not that it's a bad idea, just that because of the "nil interface" absurdity it can happen if you accidentally mix concretely typed variables and interfaces, as in the example.

This is perfectly valid and doesn't cause the nil issue:

    return someErrorStruct{}
...where someErrorStruct is a strict that implements the "error" interface. Using structs for errors is fine, and is in fact generally preferable to singletons like io.EOF, which can (by their very nature) never be extended with more data about the error.
> absurdity

There's nothing absurd about it; interfaces are a reference type. If you have a reference to a reference, then checking the "outer" reference for nil doesn't tell you anything about the nullity of the "inner" reference. The advice is just a special case of "don't needlessly use pointers-to-pointers".

Go chose to rely heavily on nil pointers, which is a design mistake (see Tony Hoare's apology for inventing it). The resultant tension between interfaces and nils is, in my opinion, an absurd side effect that cannot be explained away as anything except an ugly wart. We should have something better than this in 2016.

I say this as someone who uses Go daily for my work and mostly likes it (despite the many warts).

I don't especially love nil either, but people make too big a deal of it. The only arguments against it are hypothetical scenarios, anecdotal examples, and appeals to Hoare's authority. While there's probably a more ergonomic design, there's no substantial evidence that nil is the catastrophe it's made out to be. Using terms like "absurdity" and "catastrophe" seems overly dramatic without some decent evidence.
I don't think I'm being overly dramatic, actually. I deal with nil oversights on a daily basis during development, and I would say that it is is the main source of unexpected crashes in anything. It equally applies to other languages such as Ruby and Python.

It's exacerbated by the fact that Go chose to make things like maps, slices and channels pointers, too. It has an excellent philosophy about zero values (so you can't get nil strings, even though they are pointers internally), yet goofed when it came to something as intuitive as "var foo []string", and claimed this behaviour to be a feature. The (nil, nil) interface is just icing on a crappy cake.

The fact that such a new language as Go doesn't have a way to express missing values safely should be disappointing to developers.

The return type would still be the error interface. If you want more information than the error interface you can just use a type switch/assertion.