Language-level sum types are something that I miss a lot when I'm writing Go. I find myself using this error-prone pattern whenever I'm trying to represent state:
type PersonType string
const (
EmployeePersonType PersonType = "Employee"
ManagerPersonType PersonType = "Manager"
ClientPersonType PersonType = "Client"
)
I'm not the only one[1]. Another option is to use iota. type PersonType int
const (
EmployeePersonType PersonType = iota
ManagerPersonType
ClientPersonType
)
You'll then use generators such as stringer or jsonenums[2] to take care of translating your internal representations to something more system-level and printable. This gets very messy as now we need to write un/marshallers and code generators for SQL databases, NoSQL databases, JSON endpoints, etc. I'm likely to just keep doing what I'm doing.Although my described approaches aren't great, I'm glad to see people thinking about how to improve it with tooling. For reference, this is the same thing in Haskell:
data Person = Employee | Manager | Client
I really prefer this format because the set of possible Person type options is explicitly defined and easy to exhaustively check. You'll get no type coercion from arbitrary strings like "Daughter".And you can also extra data types using type constructors:
data ApptTime = NotScheduled | WalkIn | At UTCTime
At least by attempting to use sum types in Go, you get some compiler checks, which are a lot better than none.Has anyone figured out a better way?
[1] https://github.com/kubernetes/kubernetes/blob/master/pkg/api...