Hacker News new | ask | show | jobs
by badhombres 1655 days ago
Great writeup. Some of the points are moot now that generics are being released, but some very valid concerns.

I would also add that Enums + Exhaustive Switch is a very very weak area in Go that would really benefit the language a ton. I've used those features in other languages and that's one of the things I miss the most, especially when dealing with a ton of web API's that have a defined set of values for properties.

Able to have the confidence that we're checking for every situation that could occur on an enum type across the codebase is one less thing I need to worry about.

4 comments

> Able to have the confidence that we're checking for every situation that could occur on an enum type across the codebase is one less thing I need to worry about.

golangci-lint (https://github.com/golangci/golangci-lint) is an absolute must, and includes https://github.com/nishanths/exhaustive which will check this for you.

my 50 cents:

I'd rather just use go vet + staticcheck. Way simpler, no complex configuration, and no license concerns :)

and then you can create a file like the following and add whatever analyzer provides value for your specific case (including this exhaustive), easily. Example: https://github.com/FiloSottile/mkcert/blob/master/analysis.g...

don't let perfect be the enemy of good. =)
Configurable linters are usually best avoided, because it's too easy to remove a check rather than fix your code, in a crunch.
If you can write the indulgence (permission to sin) into the code it becomes self-documenting and that seems reasonable

e.g. #![allow(dinosaur::nonsense)] in Rust tells the tools that you know you're not supposed to do whatever dinosaur::nonsense might be, but you want to do it anyway in the following code and the hypothetical dinosaur linter shouldn't bother you about that.

When a maintenance programmer is staring at this block of code later, the fact you explicitly intended to do dinosaur::nonsense is right there, documented where it happens, and they can decide if the proper course of action is to leave that as it is, fix the code to not be dinosaur::nonsense, allow raven::stupidity because the new Raven linter is better but now warns about the same problem under a different name or what.

This is fine, in moderation! I'm objecting to the linter tool itself being configurable.
Golint is the worst precisely because it isn’t configurable, and some of the things it looks for are idiotic. “should replace i += 1 with i++” is probably the worst advice I have ever received.
I can see Go's point here though. Unlike C-style languages where i++ is an expression, in Go it's only a statement, it has no value, which eliminates some footgun opportunities.

It's a halfway house to a language like Swift or Rust where none of the assignments have value. So, in a context where you don't want a value, arguably i++ is a better choice by eliminating a footgun. I don't hate it.

If a linter is configurable it is no longer a linter.
thank you, I'm going to take a look at these!
Strongly agree here. I'd rather have this than generics, personally. Having to implement my own sum types every time is laborious (moreso than most boilerplate that people complain about) and it's also hard for users to understand (what are all of the permutations?) and extend (I added a new permutation; where are all of the sites I need to update?).
Seconded on Enums. It's annoying that they're not there.
go-sumtype[0] has completeness checking for sealed interfaces.

[0] https://github.com/BurntSushi/go-sumtype